0

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

进程.h:

private:
  myObj *data;

进程.cc:

data = new myObj[10];

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

进程.h:

private:
  std::vector<myObj> data;

进程.cc:

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

当我尝试它在执行时崩溃

*** glibc detected *** ... corrupted double-linked list: ... ***

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

4

2 回答 2

3

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

struct Other {};

struct MyObj {
    Other *p;

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

std::vector<MyObj> data;

data.push_back(MyObj());

被推送到的临时对象被data正确存储。但是,由于它是临时的,因此在推送后立即销毁。这意味着,p当临时对象被销毁时,成员被删除,因此向量的副本版本有一个悬空指针。当vector对象被销毁时,指针会再次被删除,导致堆损坏。您收到的错误消息来自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;
    }
};

需要使用 mutable 才能p在实例为 时修改成员const,并且const因为临时对象被传递给复制构造函数而需要使用。通过此更改,将项目推入向量中可以正常工作。

更好的解决方案是定义p使用 aunique_ptr代替。

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

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

在这个例子中不需要析构函数,因为默认的析构函数会破坏 p,这会导致Other实例被 删除unique_ptr

于 2012-06-16T06:51:52.850 回答
-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);
     }
 };
}

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

vector<data> myObj;
于 2012-06-16T01:30:33.270 回答