2012-06-15 87 views
0

我在這裏有一個非常奇怪的問題,希望有人能幫助我。這是代碼。C指針分配:錯誤的地址和分段錯誤

Node *fct(Node *list) 
{ 
    Node *node; 
    node = list; 
    ... 
} 

通常情況下,一切運行平穩,但在一些隨機的情況下,我得到一個分段錯誤。我與GDB deb deb。通常地,列表和節點的地址都是0x80d4000,但是當發生Segfault時,節點的地址= 0x400。 (列表仍然是0x80d4000)。
我真的不明白這可能會出錯,有什麼想法嗎?

+2

也許你在其他地方損壞了內存。我們需要更多的代碼,給定的片段沒有任何問題。 – kan

+1

很多想法,但沒有更多的代碼,不知道哪個想法對你的情況實際上有用。 – StarPilot

+1

IT不是這裏錯誤的代碼,而是任何人調用fct()函數來傳遞無效數據。 (可能它會嘗試傳遞一個NULL指針成員的地址) – nos

回答

1

這是不夠的代碼是肯定的,但我懷疑某個地方,你傳遞一個地址(指針)的副本,並對COPY(如malloc)進行修改;而不是傳遞這個地址的地址(指針指向一個指針),所以你實際上修改了指針而不是其中一個副本。

一個例子來說明什麼我談論:

int dostuff(char* str) 
{ 
    str = malloc(sizeof(char)); 
    str[0] = 0x42; 
    return 1; // size of string. 
} 

int main(int argc, char** argv) 
{ 
    char* mystr = NULL; 
    unsigned int strlength = 0; 
    strlength = dostuff(mystr); 
    printf("%s\n", mystr); // Segfaults here: mystr == NULL. 
    free(mystr); 
    return 0; 
} 

所以這裏發生的事情:

  1. 您創建一個新的字符指針設置爲NULL(更好,如果你想要的realloc , 例如)。
  2. 您將其值(NULL)傳遞給dostuff。該函數複製此值(使用char *類型),並修改此副本。
  3. printf訪問mystr進行打印,並嘗試從NULL [0](0)中讀取時,會出現段錯誤。

當然,main的其餘部分沒有執行。

這就是爲什麼有人會陷入這個坑:通常,當你使用一些指針與一個功能做一些修改,你修改它的內容,而不是它的地址。當你修改它的地址時,你幾乎總是(除了像這樣的情況外)有修改它的函數返回它的新地址。像在address = malloc(size)。另一方面,如果你想設置一個POINTER(而不是明顯的內容),你需要將它的地址拷貝傳遞給函數。這裏是上面的代碼的工作版本:

int dostuff(char** str) 
{ 
    (*str) = malloc(sizeof(char)); 
    (*str)[0] = 0x42; 
    return 1; // size of string. 
} 

int main(int argc, char** argv) 
{ 
    char* mystr = NULL; 
    unsigned int strlength = 0; 
    strlength = dostuff(&mystr); 
    printf("%s\n", mystr); // Now works: mystr is allocated. 
    free(mystr); 
    return 0; 
} 

所以請記住:有疑問時,返回的指針,並獲得其他變量(strlength此處)的地址。如果不可能,請對您正在操作的數據的實際類型非常小心,並在修改後仔細檢查您的地址。

我希望它有幫助。