2012-06-15 88 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此处)的地址。如果不可能,请对您正在操作的数据的实际类型非常小心,并在修改后仔细检查您的地址。

我希望它有帮助。