0

我有一个错误,似乎导致访问已被清除的内存。有 2 个类 - B 类(包含 C 类的结构实例和 D 类的 unique_ptrs)和 A 类,它包含 B 类对象的向量。以下是导致该错误的区域的代码结构:

void foo{
  A localA(...);
  bar(&localA);
  baz(localA);
}

void bar(A* a) {
  C c1 = constructLocalC1();
  D d1 = constructLocalD1();
  a.insertB(c1, &d1);
}

请注意, insertB 将调用 B 类的构造函数 - 类似于:

void A::insertB(C c, D* d) {
  bVector.push_back(B(c, d));
}

B::B(C cIn, D* dIn) : c_(cIn) { d_ = make_unique<D>(*dIn); }  

B {
public:
  B(C c, D* d);
  C c_;
  std::unique_ptr<D> d_;
}

的实现constructLocalC1()看起来像(类似 for constructLocalD1()

 C constructLocalC1() {
   C c1;
   c1.blah = computeBlahParameter(); // blah is of type int
   c1.bleh = computeBlehParameter(); // bleh is of type double
   return c1;
}

观察结果是,当 baz 尝试访问 localA 中存在的 c1(的副本)时,其中的值已损坏,并且与 bar 设置的值不同。我从这个观察中得出的结论是,存储 B 的向量正在存储一个已被取消分配的元素。

我知道通过这里的代码片段理解根本原因有点复杂,因为这是高度抽象的 - 很高兴提供所需的更多具体细节。

此代码片段中的潜在陷阱和内存泄漏原因是什么?什么是调试的好方法?

4

1 回答 1

0

您的问题可能是您没有在内部对象上动态分配内存bar。如果您在未显式或隐式动态分配的函数中创建对象(使用new或使用临时对象),则您的对象将在堆栈​​上创建,并且一旦超出范围就会被销毁(在你的情况下,当函数返回时)。一种选择是为插入向量中的对象分配内存,但在内存处理和释放时要非常小心,因为如果处理不当会导致内存泄漏。您还可以使用智能指针(Boost库对它们有很好的实现,但也添加了STL),这将通过 RAII 概念方法防止这种情况(有关 RAII 的更多信息,请参阅此主题:RAII 和 C++ 中的智能指针)。

于 2013-11-06T23:44:39.967 回答