C++ std::vector 指针删除和分段错误

发布于 2024-07-22 03:29:28 字数 641 浏览 7 评论 0原文

我有一个指向类的指针向量。 我需要调用它们的析构函数并释放它们的内存。 因为它们是指针向量 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;

    }

}

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

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

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

I have a vector of pointers to a class. I need to call their destructors and free their memory. Since they are vector of pointers vector.clear() does not do the job.So I went on to do it manually like so :

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;

    }

}

The printf in there is since I have a talking destructor to see in which Chromosome the segmentation fault happens. When clearPool() is called and say we got a size of 100, it can give a segmentation fault in any Chromosome between 0 and 100.

I have no idea why this might be happening nor do I have a way to actually find what's wrong since while debugging with breakpoints all I see is that it happens in there at random chromosomes.

I am using codeblocks IDE and the gdb debugger. The stack trace when the segmentation fault happens has 4 memory addresses and a function wsncpy().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

一江春梦 2024-07-29 03:29:28
void Population::clearPool( std::vector <Chromosome*> & a )
{
   for ( int i = 0; i < a.size(); i++ ) {
      delete a[i];
   }
   a.clear();
}

请注意,向量是通过引用传递的。 在您的代码中,使用向量的副本,这意味着它在调用程序中未更改。 因为您删除了副本中的指针,所以原始文件中的指针现在全部无效 - 我怀疑您正在以某种方式使用这些无效指针,而这些方式未在您发布的代码中显示。

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

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

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

vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );
void Population::clearPool( std::vector <Chromosome*> & a )
{
   for ( int i = 0; i < a.size(); i++ ) {
      delete a[i];
   }
   a.clear();
}

Notice that the vector is passed by reference. In your code, a copy of the vector is used, which means that it is unchanged in the calling program. Because you delete the pointers in the copy, the pointers in the original are now all invalid - I suspect you are using those invalid pointers in some way not shown in the code you posted.

As a couple of template solutions have been posted that use C++ library algorithms, you might also want to consider a template solution that does not:

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

Using this you can free any container of dynamically allocated objects:

vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );
原谅过去的我 2024-07-29 03:29:28

与(@1800信息)相比略有修改的版本。

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


std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());

Slight modified version compared to (@1800 INFORMATION).

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


std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());
人生百味 2024-07-29 03:29:28

我不知道你为什么崩溃,但我猜一种可能性是向量的大小与你传入的大小不同。我还注意到你正在从 0 迭代到 size-2,你是吗?不是说要一路走到最后吗?

使用惯用的 C++ 删除数组中所有项目的一种方法如下:

template<class T>
class deleter
{
  public:
    void operator()(const T* it) const
    {
      delete it;
    }
};

std::for_each(a.begin(), a.end(), deleter<Chromosome>());

I don't know why you are crashing, but I guess that one possibility is that the size of the vector is not the same as the size you are passing in. Also I notice you are iterating from 0 to size-2, do you not mean to go all the way to the end?

One way to delete all of the items in the array using idiomatic C++ is something like this:

template<class T>
class deleter
{
  public:
    void operator()(const T* it) const
    {
      delete it;
    }
};

std::for_each(a.begin(), a.end(), deleter<Chromosome>());
萌吟 2024-07-29 03:29:28

顺便说一句,Boost lambda 已经有一个用于删除指针序列的函子:

std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());

Boost lambda already has a functor for deleting sequences of pointers, by the way:

std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());
沙与沫 2024-07-29 03:29:28

您确定向量中的每个指针都指向不同的对象吗?
(即,两个指针并不都指向同一个对象,而您正尝试删除该对象两次。

您确定在调用此方法之前不会删除某些指针吗?
(即你确定列表中的每个指针都指向一个有效的对象吗?)

Are you sure that each pointer in the vector points to a different object?
(i.e. that two pointers don't both point to the same object, which you're trying to delete twice.

Are you sure that you don't delete some of the pointers before calling this method?
(i.e. are you sure that each pointer in the list points to a valid object?)

盗梦空间 2024-07-29 03:29:28

我发现了问题。

它位于最隐蔽的地方(不是别人,正是愚蠢的老我)。

有些人可能已经猜到这是一个遗传算法程序。 这是我正在制作的教程。 我从我制作的轮盘赌函数中随机选择染色体的交叉点。 嗯...里面有一个-1,不应该在那里。 这实际上摧毁了一切,并最终导致分段错误。

谢谢大家的帮助,我在这篇文章中看到了一些非常好的做法,我打算遵循这些做法

I found the problem.

It was in the most well hidden (by none other than stupid old me) place it could be.

As some might have guessed this is a genetic algorithms program. It is for a tutorial I am making. I was choosing the crossover points for the chromosomes randomly from a roulette wheel function which I made. Well ... inside there, there was a -1 which should not be there. That destroyed literally everything, and eventually lead to a segmentation fault.

Thank you all for your help, I saw some really good practises in this post which I intend to follow

楠木可依 2024-07-29 03:29:28

我建议使用智能指针(即:auto_ptr)而不是原始指针,只使用 vector::clear 方法来为每个元素调用析构函数

I recommend to use smart pointer (ie:auto_ptr) instead of raw pointer and just use vector::clear method that will call the destructor for each element

静赏你的温柔 2024-07-29 03:29:28

最可能的原因是对同一地址调用两次delete。 如果您将一个对象多次添加到向量中,则可能会发生这种情况。 要检测此情况,请插入一些语句,该语句将输出您将删除的对象的地址。

printf( "will delete %d\n", (int)c );
delete c;

The most likely reason is calling delete twice for the same address. This can happen if you added one object more than once to the vector. To detect this insert some statement that will output the address of the object you will then delete.

printf( "will delete %d\n", (int)c );
delete c;
飘落散花 2024-07-29 03:29:28
void Population::clearPool(std::vector<Chromosome*>& a)
{
    for(size_t i = 0; i < a.size(); i++) {
        delete a[i];
    }

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

    a.clear();
}
孤独岁月 2024-07-29 03:29:28

看来,代码中的某些指针没有引用正确的 Chromosome 对象。 如果您尝试由于代码而两次删除某些对象,则可能会发生这种情况:

Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time

您可能会从 Boost Pointer Container Library 以避免类似错误

It seems, that some pointers in your code do not reference correct Chromosome objects. This may happen, if you try to delete some objects twice as a result of code:

Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time

You may find useful ptr_vector from Boost Pointer Container Library in order to avoid similar errors

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文