【发布时间】:2021-02-16 03:13:13
【问题描述】:
警告:我知道我没有为这段代码提供任何上下文,一般来说这是非常必要的,但我认为由于错误/情况的性质,这不是必需的,它会不必要地混淆事情。话虽如此,如果您建议我编辑问题以在代码中添加上下文和定义,我当然会这样做。
在下面的代码中
Person *root = list[0];
Element start = {root, NULL};
Stack Q = {&start};
i = 0;
Element *next_elem = NULL;
Element *first = NULL;
int cn;
Person *p = NULL;
puts("Starting stack process...");
while(Q.start != NULL)
{ // process the first element, look at their info and children
printf("Name: %s\n", Q.start ->prsn ->name);
cn = Q.start ->prsn ->cn;
printf("Nº of children: %i\n", cn);
// look at their children and put them in the stack
first = Q.start;
for(i = 0; i < cn; i++)
{ if((next_elem = (Element*)malloc(sizeof(Element))) == NULL) return 1;
next_elem ->prsn = first ->prsn ->children[i];
first -> next = next_elem;
first = next_elem;
}
Q.start = Q.start -> next;
}
我收到以下错误
Process 5864 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x30)
frame #0: 0x0000000100000de0 GTree_DFS`main at GTree_DFS.c:101:32
98 first = Q.start;
99 for(i = 0; i < cn; i++)
100 { if((next_elem = (Element*)malloc(sizeof(Element))) == NULL) return 1;
-> 101 next_elem ->prsn = first ->prsn ->children[i];
102 first -> next = next_elem;
103 first = next_elem;
104 }
Target 0: (GTree_DFS) stopped.
这可以通过将 for 循环条件从 i < cn 更改为 i < cn - 1 来解决。所以这应该意味着问题是我要越界了,对吧?好吧,不,因为如果我修改代码,在 for 循环之前添加像 p = first ->prsn ->children[3]; 这样的行,它不会引发任何错误:
Process 5897 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x30)
frame #0: 0x0000000100000ddf GTree_DFS`main at GTree_DFS.c:101:32
98 p = first ->prsn ->children[3]; // No segfault here
99 for(i = 0; i < cn; i++)
100 { if((next_elem = (Element*)malloc(sizeof(Element))) == NULL) return 1;
-> 101 next_elem ->prsn = first ->prsn ->children[i]; // Segfault here
102 first -> next = next_elem;
103 first = next_elem;
104 }
Target 0: (GTree_DFS) stopped.
如果段错误不是由于i 索引,那么为什么将 i < cn 更改为i < cn - 1 会解决它?这个错误是不是不一致?
【问题讨论】:
-
标题的隐形潜台词是“未定义的行为”。当您对代码进行看似无害的更改时,行为发生变化是很常见的。
-
我应该在标题中添加未定义的行为吗?
-
没有必要。
-
@CMB 在这种情况下,您的头衔将成为您的答案。答案是“未定义的行为”。
-
我一直怀疑
pointer1 -> pointer2 -> member没有对中间指针值进行任何检查,但是从不完整的代码中很难看出发生了什么。您应该找出导致段错误的确切原因:NULL指针、未初始化的指针、悬空指针等。
标签: c segmentation-fault stack