我在这里遇到了一个非常奇怪的问题,希望有人可以帮助我。这就是代码。
Node *fct(Node *list)
{
Node *node;
node = list;
...
}
通常一切运行顺利,但在某些随机情况下,我会遇到分段错误。我用 GDB 调试。通常列表和节点的地址都是0x80d4000,但是当发生Segfault时,节点的地址= 0x400。(列表仍然是 0x80d4000)。
我真的不知道这可能会出错,有什么想法吗?
我在这里遇到了一个非常奇怪的问题,希望有人可以帮助我。这就是代码。
Node *fct(Node *list)
{
Node *node;
node = list;
...
}
通常一切运行顺利,但在某些随机情况下,我会遇到分段错误。我用 GDB 调试。通常列表和节点的地址都是0x80d4000,但是当发生Segfault时,节点的地址= 0x400。(列表仍然是 0x80d4000)。
我真的不知道这可能会出错,有什么想法吗?
这还不足以确定代码,但我怀疑在某个地方,您传递了地址的副本(指针)并在 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;
}
所以这就是正在发生的事情:
dostuff
. 该函数复制此值(具有 char* 类型),并修改此副本。当然,其余的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
此处)。如果不可能,请对您正在操作的数据的实际类型非常谨慎,并在修改后仔细检查您的地址。
我希望它有所帮助。