【问题标题】:Apparently inconsistent segmentation fault? [closed]显然不一致的分段错误? [关闭]
【发布时间】: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 &lt; cn 更改为 i &lt; cn - 1 来解决。所以这应该意味着问题是我要越界了,对吧?好吧,不,因为如果我修改代码,在 for 循环之前添加像 p = first -&gt;prsn -&gt;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 &lt; cn 更改为i &lt; cn - 1 会解决它?这个错误是不是不一致?

【问题讨论】:

  • 标题的隐形潜台词是“未定义的行为”。当您对代码进行看似无害的更改时,行为发生变化是很常见的。
  • 我应该在标题中添加未定义的行为吗?
  • 没有必要。
  • @CMB 在这种情况下,您的头衔将成为您的答案。答案是“未定义的行为”。
  • 我一直怀疑pointer1 -&gt; pointer2 -&gt; member 没有对中间指针值进行任何检查,但是从不完整的代码中很难看出发生了什么。您应该找出导致段错误的确切原因:NULL 指针、未初始化的指针、悬空指针等。

标签: c segmentation-fault stack


【解决方案1】:

我可能完全糊涂了,但循环似乎是错误的。

你在第 100 行分配了next_elem, 它似乎有一个成员是 一个指针,称为prsn

但是在分配过程中,那个指针是没有值的,所以在下一次循环中 它将通过first 变量使用(查看第 101 行,LHS),这会导致不可预知的结果...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2017-03-12
    • 2014-07-01
    相关资源
    最近更新 更多