我想了解在現代C++中使用智能指針,並且我寫了一個小的,簡單的程序來測試valgrind
。問題是,下面的例子:valgrind和std :: unique_ptr --- false positive or not?
#include <iostream>
#include <memory>
class Base {
private:
virtual double meth_1(double x) const = 0;
virtual void meth_2(int y) const = 0;
protected:
Base()
{
std::cout << "ctor of base for: " << this << std::endl;
}
public:
virtual ~Base()
{
std::cout << "dtor of base for: " << this << std::endl;
}
double IMeth_1(double x) const
{
return meth_1(x);
}
void IMeth_2(int y) const
{
meth_2(y);
}
};
class Derived_1 : public Base {
private:
double meth_1(double x) const final
{
return x + 5.0;
}
void meth_2(int y) const final
{
std::cout << (y + 5) << std::endl;
}
public:
Derived_1() : Base()
{
std::cout << "ctor of Derived_1: " << this << std::endl;
}
~Derived_1()
{
std::cout << "dtor of Derived_1: " << this << std::endl;
}
};
class Derived_2 : public Base {
private:
double meth_1(double x) const final
{
return x + 10.0;
}
void meth_2(int y) const final
{
std::cout << (y + 10) << std::endl;
}
public:
Derived_2() : Base()
{
std::cout << "ctor of Derived_2: " << this << std::endl;
}
~Derived_2()
{
std::cout << "dtor of Derived_2: " << this << std::endl;
}
};
void Fun(const Base& crBase)
{
crBase.IMeth_2(5);
}
int main(int argc, char* argv[]) {
std::unique_ptr<Base> upBase;
for (std::size_t idx = 0ul; idx < 2ul; idx++) {
upBase = std::make_unique<Derived_1>();
std::cout << upBase->IMeth_1(idx) << std::endl;
upBase->IMeth_2(idx);
std::cout << "----------" << std::endl;
}
for (std::size_t idx = 0ul; idx < 2ul; idx++) {
upBase = std::make_unique<Derived_2>();
std::cout << upBase->IMeth_1(idx) << std::endl;
upBase->IMeth_2(idx);
std::cout << "----------" << std::endl;
}
upBase = std::make_unique<Derived_1>();
Fun(*upBase);
return 0;
}
給出了一個內存泄漏時valgrind --leak-check=full --show-leak-kinds=all <prog_name>
運行:
==32350== HEAP SUMMARY:
==32350== in use at exit: 72,704 bytes in 1 blocks
==32350== total heap usage: 6 allocs, 5 frees, 72,744 bytes allocated
==32350==
==32350== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==32350== at 0x4C28C10: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32350== by 0x4EBE1EF: pool (eh_alloc.cc:117)
==32350== by 0x4EBE1EF: __static_initialization_and_destruction_0 (eh_alloc.cc:244)
==32350== by 0x4EBE1EF: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:307)
==32350== by 0x400F279: call_init.part.0 (in /usr/lib/ld-2.22.so)
==32350== by 0x400F38A: _dl_init (in /usr/lib/ld-2.22.so)
==32350== by 0x4000DB9: ??? (in /usr/lib/ld-2.22.so)
==32350==
==32350== LEAK SUMMARY:
==32350== definitely lost: 0 bytes in 0 blocks
==32350== indirectly lost: 0 bytes in 0 blocks
==32350== possibly lost: 0 bytes in 0 blocks
==32350== still reachable: 72,704 bytes in 1 blocks
==32350== suppressed: 0 bytes in 0 blocks
==32350==
==32350== For counts of detected and suppressed errors, rerun with: -v
==32350== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
是與72,704字節仍在使用在退出該塊假陽性,還是我誤用智能指針?我假設我沒有做任何形式的切片,因爲每當對象被刪除時都會調用基礎dtor。
對不起,如果這是一個愚蠢的問題,但我找不到在SO中的任何valgrind/false positive/unique_ptr相關主題。此外,我不知道可能在unique_ptr
中創建的任何附加塊與shared_ptr
類似,以跟蹤該對象。
編輯:不是Still Reachable Leak detected by Valgrind重複,因爲在我的情況,我不使用線程(和valgrind
衆所周知,產生假陽性的,特別是環境的openmpi)。此外,在另一個問題中,通過對所提供的代碼進行適當修改來解決問題。不過,沒有什麼調用真實記憶任何共識泄漏 ---也就是說,應該是在出口仍在使用是的可達塊被視爲內存泄漏,還是不行。
看起來像Valgrind的錯誤,它的檢測自身分配...您'的std :: unique_ptr'的使用看起來不錯。 – Quentin
看着代碼看起來不錯,但你應該嘗試減少它,因爲在這裏似乎還有相當多的不必要的代碼來重現問題。作爲在valgrind中測試小事情的一般規則,將整個測試放入一個函數中並多次調用它。然後,如果丟失塊的數量增加,你知道你有一個真正的內存泄漏。 – Dave
謝謝你們兩位的評論。我會嘗試這個函數的方法來查看在出口處使用的塊是否增加或保持不變,@Dave。 –