-1

我在 C 中遇到了一个有趣的问题,当从 main 调用外部方法时,该方法试图 strtok 通过引用传递给它的本地(主)字符串。如果我在 main 中 strtok 字符串,它会按预期工作,但如果我调用外部方法,它会因段错误而失败。Valgrind 在访问 strtok 结果的第一个元素时的输出:

Address 0xfffffffffeffebc0 is not stack'd, malloc'd or (recently) free'd

--- 测试.c ---

extern void tt(char* x);

main(argc, argv) 
    int argc;
    char *argv[];
{
    char line[5000];
    // if I uncomment the following two lines and comment above it works as expected
    // char * line;
    // line = malloc(5000);
    strcpy(line, "hello world");
    printf("%d\n", sizeof(line));
    tt(line);
}

--- test2.c ---

void tt(char* l) {
    char* x = strtok(l, " \t");
    printf("%p\n", x);
    printf("%c\n", x[0]);
}

编译

gcc -c test2.c -o test2.o
gcc test.c test2.o

恕我直言,它应该打印出如下内容:

./a.out
0x.....
h

但相反,我在打印“h”时遇到了段错误。

有人可以解释这种行为吗?

谢谢。

4

1 回答 1

7

在文件中

--- test2.c ---

void tt(char* l) {
    char* x = strtok(l, " \t");
    printf("%p\n", x);
    printf("%c\n", x[0]);
}

您还没有包含string.h,因此编译器假定返回类型为intfor strtok。因此这条线

char *x = strtok(l, " \t");

没有分配正确的指针x(如 valgrind 输出所示,您的指针至少为 64 位,但int很可能只有 32 位)。然后取消引用损坏的指针会导致分段错误。

于 2013-05-14T16:09:55.593 回答