【问题标题】:gcc -O segmentation faultgcc -O 分段错误
【发布时间】:2015-09-23 09:56:10
【问题描述】:

这是在二进制树中插入数据的代码。如果我用基本的 gcc main.c -o main 编译它,这段代码就可以完美运行。

/**
     * Insert a new gateway in the tree, at the position corresponding to the
     * subnet address.
     *
     * addr    : Subnet address
     * netmask : Subnet mask
     * gw      : gateway identifier
     * 
     * return  : void.
     */
    void insertMyAlgo(unsigned int addr, unsigned int netmask, unsigned int gw)
    {
       struct node* noeud;
       int i;
       int maskBit = countMaskBit(netmask);

       // Going down in the tree until next mask bit = 0.
       noeud = arbre;
       for (i = 31; i > 31 - maskBit; i--)
       {
          // Bit = 1, go down in the right child.
          if ((addr >> i) & 0x1)
          {
             if (noeud->fd == NULL)
                noeud->fd = allocNode();
             noeud = noeud->fd;
          }

          // Bit = 0, go down in the left child.
          else
          {
             if (noeud->fg == NULL)
                noeud->fg = allocNode();
             noeud = noeud->fg;
          }
       }

       // Insert the gateway in the node corresponding to our subnet address.
       noeud->gateway = gw;
    }

我想使用 -O 选项来优化查找树、查找特定键所花费的时间。当我使用这个 -O 选项执行我的 main 时,我得到一个段错误。 Gdb 给了我以下信息:

Program received signal SIGSEGV, Segmentation fault. insertMyAlgo
(addr=12288, netmask=<optimized out>, gw=3238068734)
    at mainbinaireBench.c:125 125            if (noeud->fg == NULL)
(gdb) print noeud->fg Cannot access memory at address 0x8

所以错误似乎在这里:

 // Bit = 0, go down in the left child.
 else
 {
    if (noeud->fg == NULL)
       noeud->fg = allocNode();
    noeud = noeud->fg;
 }

我真的不知道为什么会出现这个错误,以及为什么程序在没有这个 -O 选项的情况下工作。我真的很想让它起作用,如果你们中的一些人可以帮助我理解,那就太好了。

谢谢!

【问题讨论】:

  • 一次包含调试输出的帖子
  • 也许你向我们展示了 allocNode() 是什么。向我们展示一个我们也可以编译它的最小代码。
  • 'debug' 和优化的编译代码之间可能的区别可能是未初始化的变量设置为 0。在 valgrind 下运行程序并检查它的内容。
  • 在发布我的代码后,我检查了 allocNode ...并且没有返回,而签名是 strcut node* allocNode(){} 。我忘记了~~。我只是添加了回报,它现在可以工作了。谢谢!
  • gcc -Wall -Wextra -g编译

标签: c gcc memory segmentation-fault binary-tree


【解决方案1】:

如果没有Short Self Contained Example,就不可能确定问题出在哪里

但是有一些调试技术可以帮助您找出问题所在。 在您的代码中添加几个asserts

void insertMyAlgo(unsigned int addr, unsigned int netmask, unsigned int gw)
{
   struct node* noeud;
   int i;
   int maskBit = countMaskBit(netmask);

   // Going down in the tree until next mask bit = 0.
   assert( arbre!=NULL );
   noeud = arbre;
   for (i = 31; i > 31 - maskBit; i--)
   {
      // Bit = 1, go down in the right child.
      if ((addr >> i) & 0x1)
      {
         if (noeud->fd == NULL)
         {
            noeud->fd = allocNode();
            assert( noeud->fd!=NULL );
            assert( noeud->fd->fd==NULL );
            assert( noeud->fd->fg==NULL );
         }
         noeud = noeud->fd;
      }

      // Bit = 0, go down in the left child.
      else
      {
         if (noeud->fg == NULL)
         {
            noeud->fg = allocNode();
            assert( noeud->fg!=NULL );
            assert( noeud->fg->fd==NULL );
            assert( noeud->fg->fg==NULL );
         }
         noeud = noeud->fg;
      }
   }

   // Insert the gateway in the node corresponding to our subnet address.
   noeud->gateway = gw;
}

如果现在这些断言中的任何一个失败了,您就会更好地了解正在发生的事情。如果没有失败,则说明您减少了搜索空间,问题出在其他地方。
完成调试后,您甚至可以将断言留在那里。只需为发布版本定义 NDEBUG,断言中的所有代码都将被省略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2014-08-16
    • 2016-10-13
    • 2011-10-02
    • 1970-01-01
    • 2014-05-16
    相关资源
    最近更新 更多