C ++:过滤节点值时崩溃

时间:2013-12-27 09:28:13

标签: c++ pointers

下面的代码是我在项目代码中遇到的问题的模拟。 在这段代码中,我有一个向量,其中有一些值。现在,我想根据一些标准从这个原始向量中过滤掉一些值,并将它们存储在一个新的向量中。

这里的主要问题是“节点”中的指针变量。我甚至做了深层复制,以避免双重免费()。但即使这样,它也会给出相同的例外。

代码:

#include <iostream>
#include <vector>

using namespace std;

class node
{
    public:

    int a;
    double *ptr;

    node()
    {
        a = 0;
        ptr = NULL;
    }

    ~node()
    {
        if(ptr)
        {
            delete [] ptr;
        }
    }
};

int main()
{
    vector <node> original(10);
    cout << "Filling values in Original Copy : " << endl ;

    for(int i=0; i<10; i++)
    {
        original[i].a = 0;
        original[i].ptr = new double[20];
    }

    vector <node> mod2;
    cout << "Finding Nodes with value mod 2 : "  << endl ;

    for(int i=0; i<10; i++)
    {
        if(original[i].a%2 == 0)
        {
            node temp;
            temp.a = original[i].a;

            // Deep Copy
            temp.ptr = new double[20];    
            for(int j=0; j<20; j++)
            {
                temp.ptr[j] = original[i].ptr[j];
            }

            mod2.push_back(temp);
            temp.ptr = NULL; // To avoid memory deallocation
        }        
    }


   return 0;
}

2 个答案:

答案 0 :(得分:2)

node类违反了rule of three。您需要添加复制构造函数和复制赋值运算符。

如果没有这个,只要复制node的实例(通常由std::vector<node>完成),您的代码就会结束double-deleting memory

在向temp.ptr添加NULL后手动设置tmpvector的黑客行为有所帮助。但是,这既不是一个干净的解决方案,也不是一个强大的解决方案(因为它不需要处理所有情况)。

答案 1 :(得分:0)

每次将元素推入mod2向量时,增加其大小。为了做到这一点,它正在破坏先前保存的内存并为其分配新的块。在这样做时,它调用默认复制构造函数,默认情况下执行浅复制。

您可以通过以下方式解决此问题:

  1. 重载默认复制构造函数
  2. 预先保留mod2的大小(因为你知道它不能大于原始矢量)

    编辑:你也可以查看@NPE提到的rule of three