我有一个错误,似乎导致访问已经被清除的内存。 有两个类--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()
的实现看起来像(类似于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的向量存储了一个已经解除分配的元素。
我知道通过这里的代码片段了解根本原因有点复杂,因为这是非常抽象的 - 很高兴提供所需的更具体的细节。
此代码段中有哪些潜在的陷阱和内存泄漏原因?什么是接近调试的好方法?
答案 0 :(得分:0)
您的问题可能是您没有在bar
内的对象上动态分配内存。
如果在函数中创建一个非显式或隐式动态分配的对象(使用new
,或者使用临时对象),那么您的对象就会在堆栈上创建,并且会立即销毁它们。它们超出范围(在您的情况下,函数返回时)。一个选项是为插入到向量中的对象分配内存,但在内存处理和释放时要非常小心,好像处理不当会导致内存泄漏。你也可以使用智能指针(Boost
库有一个很好的实现,但也添加在STL
),这将通过RAII概念方法防止这种情况(有关RAII的更多信息,请看这个话题:RAII and smart pointers in C++)。