从(共享指针的)向量分配值到共享指针导致分段错误c ++

时间:2011-08-17 09:13:04

标签: c++ segmentation-fault while-loop shared-ptr

在我的代码中,我有一个名为vector <vector <vector <vector <std::tr1::shared_ptr<foo> > > > >的{​​{1}}。嵌套向量具有模拟物理盒位置的作用。我还有一个导致分段错误的while循环:

foosBoxes

我尝试过的一些事情:
1.我试图使用vector<std::tr1::shared_ptr<foo> >::iterator fooit = foosBoxes[x][y][z].begin(); //x,y,z are valid integer std::tr1::shared_ptr<foo> aFoo; while (fooit != foosBoxes[x][y][z].end()){ aFoo = *fooit; //this cause segmentation fault fooit++; //some stuff which does not have an effect on fooit; } ,但这不起作用 分段故障大致发生在几千分之一循环之后 我试图解决这个问题,而valgrind经历了这个步骤 在崩溃的循环中,我在可疑线路之前和之后打印了一个运行计数器。在线之前,我得到8次打印(矢量的大小)以及在我打印7次之后。

我怎么能弄清楚这一点?

更新
我在主循环之前添加了一个循环:

aFoo = *fooit++

产生相同的结果。

更新
根据gdb:

  

编程接收信号SIGSEGV,分段故障。   0x000000000043e400旋转(kkk = 1214)at   /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/boost_shared_ptr.h:153   153 dispose();

我认为boost_shared_ptr.h中的相应函数是

int kkk = 1214
int c = 0;
while (c < foosBoxes[x][y][z].end()){
   aFoo = foosBoxes[x][y][z][c++];
   printf("%i\t, kkk);
   fflush(stdout);
}

void release() // nothrow { if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1) { dispose(); //this is line 153 #ifdef __GTHREADS _GLIBCXX_READ_MEM_BARRIER; _GLIBCXX_WRITE_MEM_BARRIER; #endif if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1) destroy(); } } 在文件的其他位置定义:

dispose()

可能原因是对shared_ptr的管理错误,我应该切换回常规指针吗?

更新
另一个测试结果相似:

int kkk = 1214 int c = fooBoxes [x] [y] [z] .size(); while(c&gt; = 0){    aFoo = foosBoxes [x] [y] [z] [c--];    printf(“%i \ t,kkk);    fflush(stdout中); }

这次程序在第三次迭代中崩溃。如果问题是错误的分配,那么程序应该在第一次迭代中压垮(在第一次迭代中程序崩溃的相反方向)。

5 个答案:

答案 0 :(得分:1)

//some stuff which does not have an effect on fooit;

但这些东西对foosBoxes [x] [y] [z]有什么影响吗? 特别是它删除元素或导致向量重定位?如果是这样,fooit无法与foosBoxes [x] [y] [z] .end()进行有意义的比较。

此外,循环中的aFoo会发生什么?如果这得到一个无效值,稍后对它的赋值将导致未定义的行为。

尝试从循环中删除some stuff。如果这有效,那么东西就包含了一个bug。如果循环仍然失败,则在进入循环

之前,原因必须是fooxBoxes []中的无效值

我没有ValGrind的经验。但我使用过类似的产品。请检查您是否已将ValGrind配置为最严格的设置。这可能会使得使用它变得非常缓慢,但希望能找到错误。

答案 1 :(得分:0)

你是代码,因为它看起来没问题,我唯一能想到的是x y z有效吗? operator[]无限制检查...

答案 2 :(得分:0)

debug mode中使用libstdc ++运行代码。它将对迭代器,容器和算法进行额外检查,并希望有助于找到错误。

答案 3 :(得分:0)

我得出结论,问题是使用vector是错误的,因为我通过代码更新它。我不知道c++中的内存管理是如何工作的,但我相信两个向量之间发生了某种重叠。我已切换到set,现在一切正常

答案 4 :(得分:-1)

要对foosBoxes[x][y][z]元素进行操作,您还可以尝试:

while (fooit != foosBoxes[x][y][z].end()){
      vector<std::tr1::shared_ptr<foo> > *aFoo = *fooit; 
       fooit++;
      //To use the object 
     // use it as   aFoo->method()  
 }

不确定我是否明白这一点。但我目前正在使用指针迭代我的对象。