为什么我可以分配一个对象数组但不能将它们放在一个向量中?

时间:2012-06-15 22:04:43

标签: c++

我有一个类,我想要包含我创建的多个对象。现在有效的代码是:

process.h:

private:
  myObj *data;

process.cc:

data = new myObj[10];

我想将值传递给构造函数,但是我尝试将其转换为std :: vector(在修改构造函数以获取值之后)。

process.h:

private:
  std::vector<myObj> data;

process.cc:

for (int m=0; m<10; m++) data.push_back( myObj(1.2) );

当我尝试使用

执行时崩溃
*** glibc detected *** ... corrupted double-linked list: ... ***

当我尝试为我分配的其他数组释放一些内存时,gdb中的backtrace在析构函数中显示错误。搜索没有显示任何明显的东西。我在myObj中使用了一些静态成员变量,这可能是个问题吗?

2 个答案:

答案 0 :(得分:3)

您遇到了双重删除错误。考虑这个简单的例子:

struct Other {};

struct MyObj {
    Other *p;

    MyObj () : p(new Other) {}
    ~MyObj () { delete p; }
};

std::vector<MyObj> data;

data.push_back(MyObj());

正确存储推送到data的临时对象。但是,由于它是暂时的,它在推动后立即被销毁。这意味着,在临时销毁时删除p成员,因此该副本的向量版本具有悬空指针。当矢量对象被销毁时,指针将再次被删除,从而导致堆损坏。您收到的错误消息来自glibc代码抱怨导致的错误状态。

要解决此问题,应定义正确的复制构造函数,以将对象的所有权从临时传递到目标。三条规则说我们也应该定义赋值运算符。

struct MyObj {
    mutable Other *p;

    MyObj () : p(new Other) {}
    MyObj (const MyObj &o) : p(o.p) { o.p = 0; }
    ~MyObj () { delete p; }
    const MyObj & operator = (MyObj o) {
        using namespace std;
        swap(*this, o);
        return *this;
    }
};

当实例为p时,需要使用mutable来修改const成员,并且因为temporaries正在传递给复制构造函数,所以需要const。通过此更改,将项目推送到矢量工作正常。

更好的解决方案是定义p来改为使用unique_ptr

struct MyObj {
    std::unique_ptr<Other> p;

    MyObj () : p(new Other) {}
};

此示例中不需要析构函数,因为默认析构函数将破坏p,这将导致Other实例被unique_ptr删除。

答案 1 :(得分:-1)

您是否尝试使用向量在类中存储多个对象?我也遇到了这个问题,唯一能解决这个问题的方法就是在标题中放置使用向量的函数。我相信发生的事情是你提供的是一个类型的向量,在本例中是myObj,但.cpp看不到你将向量定义为什么类型。所以在Header中粘贴函数似乎可以修复它。我相信还有其他方法可以解决这个问题,但我没有多大意见。

示例代码:

class A
{
 private:
 vector<myObj> data;
 public:
 A();
 ~A();

 printData()
 {
     for(int i = 0; i < data.size(); i++)
     {
         printf("X position: %.2f Y position: %.2f Z position: %.2f \n", data.at(i).x, data.at(i).y, data.at(i).z);
     }
 };
}

这可能是问题,或者,这是您的命名约定。我不确定你在做什么,但数据如何* myObj;和data = new myObj [10];实际上工作?难道不是myObj =新数据[10]?如果是这样,那么你的矢量将是:

vector<data> myObj;