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

C++ : Crashing while filtering the node values

本文关键字:崩溃 节点 过滤 C++      更新时间:2023-10-16

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

这里的主要问题是"节点"中的指针变量。我什至在做深度复制以避免双重自由()。但即便如此,它也给出了同样的例外。

代码:

#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;
}

node 类违反了三法则。您需要添加复制构造函数和复制赋值运算符。

如果没有这个,每当复制node的实例时(就像std::vector<node>通常所做的那样),你的代码最终会双重删除内存。

tmp添加到vector后手动将temp.ptr设置为NULL的技巧有所帮助。但是,这既不是一个干净的解决方案,也不是一个强大的解决方案(因为它不能在需要这样做时处理所有情况)。

每次将 和 元素推送到 mod2 向量中时,它都会增加其大小。为了做到这一点,它正在破坏以前持有的内存并为其分配一个新块。在这样做时,它正在调用默认的复制构造函数,默认情况下,该构造函数正在执行浅层复制。

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

  1. 重载默认复制构造函数

  2. 提前为 mod2 保留大小(如您所知,它不能大于原始矢量)

    编辑:您还可以检查@NPE制定的三法则。