2013-05-14 27 views
-1

我在C中遇到了一個有趣的問題,當從main調用一個外部方法時,它嘗試創建一個通過引用傳遞給它的本地(主)字符串。如果我在main中創建字符串,它會按預期工作,但如果我調用外部方法,它會因segfault失敗。 Valgrind的關於訪問所述的strtok結果的第一個元素輸出:strtok在本地變量C

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

--- --- test.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」的segfault。

有人可以解釋這種行爲嗎?

謝謝。

+1

不是downvote的原因,但是您應該完全停止使用K&R樣式函數定義。 – 2013-05-14 16:05:59

+1

在http://codepad.org/7KUrMWdl – dchhetri 2013-05-14 16:06:58

+0

@ticcky上運行,爲什麼你不通過調試器並找出它崩潰的線路,以及爲什麼 – dchhetri 2013-05-14 16:08:29

回答

7

在文件

--- test2.c中---

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

您還沒有string.h,所以編譯器假定的int返回類型爲strtok。因此,該線

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

不分配適當的指針以x(作爲Valgrind的輸出所示,你的指針是64位的至少,但int很可能只有32位)。然後解除引用損壞的指針會導致分段錯誤。

+1

哇,這是令人難以置信的你找到解決方案,由於OP寫的信息量很少! – lucasg 2013-05-14 16:15:31

+3

這是編譯警告並注意它們的原因之一。當我不包含'string.h'時,gcc給出了一個關於從沒有強制轉換的整型指針的初始化的警告,並且當我添加'-Wall'時,我得到了一個'strtok'的隱式聲明警告。如果你的編譯器沒有給出這些診斷信息,那麼得到一個更好的:) – 2013-05-14 16:18:24