ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 相当奇怪的铿锵声问题

2019-07-28 10:11:57  阅读:136  来源: 互联网

标签:c vector clang g clang-2


在发布此帖子之前,我尝试了一些Google搜索,但说实话,我不知道要搜索什么.我有一个C项目,并且很乐意使用GNU编译器(g).今天我尝试用clang编译并得到一个段错误.

好的,好的,我可以解决这个问题.在仔细阅读我的代码并打印一些东西之后,我就能解决问题了.然而,这个解决方案让我感到非常麻烦和困惑.

这是情况:我使用的是树状数据结构,它存储了一个名为Ligament的类,但我将它存储在std :: vector中.我这样做是通过存储一个“children”的向量,它实际上只是向量中父对象和子对象之间的整数偏移量.通过这种方式,我可以使用this指针访问子节点,即

child = this[offset];

但是,这一点都不重要.这是这个问题:我有一个Ligament :: addChild(int)函数,它接受一个整数并将其推送到作为Ligament成员的向量的后面:

void Ligament::addChild(uint32_t offset){
   children.push_back(offset);
}

很简单的东西.一般情况下,我向addChild传递一个从名为fill的递归函数返回的参数:

//starting at root
uint32_t fill(vector<Ligament>& lVec, TiXmlElement * el){
    //store current size here, as size changes during recursion
   uint32_t curIdx = lVec.size();
   lVec.push_back(createLigament());

   //Add all of this Ligament's children
   TiXmlElement * i = el->FirstChildElement("drawable");
   for (; i; i=i->NextSiblingElement("drawable")){
      uint32_t tmp = fill(lVec, i) - curIdx;
      lVec[curIdx].addChild(tmp);

      //Does not work in clang++, but does in g++
      //lVec[curIdx].addChild(fill(lVec,i)-curIdx);
   }

   //return the ligament's index
   return curIdx;
}

fill函数在XML元素上调用,并首先通过其子元素.

对不起,如果所有这一切都不清楚,但问题的核心似乎是那个for循环.出于某种原因,我必须在将变量调用的返回值存储到addChild函数之前将其存储在变量中.

如果我不将它存储在临时变量中,似乎addChild函数不会改变子项的大小,但我无法想象为什么.

为了检查所有这些,我在这些调用之前和之后打印出子向量的大小,并且它从未超过1.只有当我使用未直接从函数返回的值调用addChild时,它似乎才起作用.

我还在addChild函数内部以及在调用之前在for循环内打印出offset的值.在所有情况下,值都是相同的,无论是clang还是g.

由于问题得到了解决,我能够继续前进,但这是我期望的.有什么我做错了吗?

如果我能做更多让这个问题更清楚的话,请随意对我大喊大叫.

另外:我现在意识到通过这些递归通过引用传递lVec可能是不好的,因为push_back调用可能导致地址改变.这是一个合理的担忧吗?

编辑:

正如人们所指出的那样,我最后关注的问题与此问题有关.填充调用有可能调整向量的大小,而lVec [curIdx] =修饰符将更改向量中的元素.这些事情发生的顺序可能会产生严重后果.

作为后续,使用tmp变量是否可以接受?仍然存在重新分配的问题……我想我会使用SHR建议的地图,然后在完成所有操作时将其转换为矢量.

解决方法:

我认为这是未定义的行为.

你推入矢量,并在同一个命令中更改它.

一个编译器可以先填充,另一个可以先得到lVec [curIdx].

如果是这种情况,当你使用map< uint32_t,uint32_t>时,它将适用于两个编译器.而不是矢量.因为map不需要内存是顺序的.

标签:c,vector,clang,g,clang-2
来源: https://codeday.me/bug/20190728/1560573.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有