C++ std ::指针删除和分段错误的向量

Lef*_*ris 5 c++ pointers memory-management segmentation-fault

我有一个指向类的指针向量.我需要打电话给他们的析构函数并释放他们的记忆.因为它们是指针向量vector.clear()不做这个工作.所以我继续这样做:

void Population::clearPool(std::vector<Chromosome*> a,int size)
{
    Chromosome* c;
    for(int j = 0 ;j < size-1;j++)
    {
       c = a.back();
       a.pop_back();
       delete c;
       printf("  %d \n\r",j);
       c = NULL;

    }

}
Run Code Online (Sandbox Code Playgroud)

那里的printf因为我有一个会说话的析构函数,可以看到哪个染色体发生了分段错误.当调用clearPool()并说我们得到100的大小时,它可以在0到100之间的任何染色体中给出分段错误.

我不知道为什么会发生这种情况,也没有办法真正找到错误,因为在使用断点进行调试时,我看到的是它发生在随机染色体上.

我正在使用codeblocks IDE和gdb调试器.发生分段故障时的堆栈跟踪有4个内存地址和一个函数wsncpy().

小智 21

void Population::clearPool( std::vector <Chromosome*> & a )
{
   for ( int i = 0; i < a.size(); i++ ) {
      delete a[i];
   }
   a.clear();
}
Run Code Online (Sandbox Code Playgroud)

请注意,向量是通过引用传递的.在您的代码中,使用了向量的副本,这意味着它在调用程序中保持不变.因为您删除了副本中的指针,原始中的指针现在都是无效的 - 我怀疑您使用的是那些无法在您发布的代码中显示的无效指针.

由于已经发布了一些使用C++库算法的模板解决方案,您可能还需要考虑一个不能的模板解决方案:

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}
Run Code Online (Sandbox Code Playgroud)

使用此方法,您可以释放任何动态分配对象的容器:

vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );
Run Code Online (Sandbox Code Playgroud)


aJ.*_*aJ. 5

与(@ 1800 INFORMATION)相比略有修改版本.

  struct DeleteFromVector
    {
        template <class T>
        void operator() ( T* ptr) const
        {
            delete ptr;
        }
    };


std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());
Run Code Online (Sandbox Code Playgroud)

  • +1,无需在呼叫站点指定类型.但是,DeleteFromVector不是一个好名字 - 它不以任何方式特定于vector. (2认同)