Visual Studio C++ 项目中的奇怪内存泄漏
Weird memory leak in Visual Studio C++ project
我用unique_ptr
。为了创建这个指针,我使用了这个代码片段:
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); //line 44
}
我在帮助 built-in memory leak checker 的帮助下测试我的项目是否存在内存泄漏。
我得到以下结果:
Detected memory leaks!
Dumping objects ->
my_header.h(44) : {228} normal block at 0x008AD568, 8 bytes long.
Data: < > A0 CB 8A 00 01 00 00 00
my_header.h(44) : {226} normal block at 0x008AD5B8, 8 bytes long.
Data: < > 00 D6 8A 00 00 00 00 00
/////////////////this error repeats many times
此外,我使用 deleaker。这个工具说,没有内存泄漏。
您不应该使用 release()
unless you're handing off the pointer-raw to someone else (hopefully another std::unique_ptr
or a std::shared_ptr
, etc). Instead you should be using reset()
,或者只是让 scope-exit 为您销毁托管对象。
使用您的代码演示好坏的最简单示例:
不好:使用release()
#include <memory>
namespace
{
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
ptr.release();
}
Valgrind 输出
==29012== 4 bytes in 1 blocks are definitely lost in loss record 1 of 87
==29012== at 0x10003B51B: malloc (vg_replace_malloc.c:303)
==29012== by 0x1001CD43D: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==29012== by 0x10000147B: std::__1::unique_ptr<int, std::__1::default_delete<int> > (anonymous namespace)::make_unique<int, int>(int&&) (in ./Sample C++)
==29012== by 0x100001337: main (in ./Sample C++)
==29012==
==29012== LEAK SUMMARY:
==29012== definitely lost: 4 bytes in 1 blocks
==29012== indirectly lost: 0 bytes in 0 blocks
==29012== possibly lost: 0 bytes in 0 blocks
==29012== still reachable: 192 bytes in 6 blocks
==29012== suppressed: 35,164 bytes in 435 blocks
==29012== Reachable blocks (those to which a pointer was found) are not shown.
==29012== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29012==
==29012== For counts of detected and suppressed errors, rerun with: -v
==29012== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)
好:使用reset()
#include <memory>
namespace
{
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
ptr.reset(); // HERE
}
Valgrind 输出
==29045== HEAP SUMMARY:
==29045== in use at exit: 35,356 bytes in 441 blocks
==29045== total heap usage: 508 allocs, 67 frees, 41,216 bytes allocated
==29045==
==29045== LEAK SUMMARY:
==29045== definitely lost: 0 bytes in 0 blocks
==29045== indirectly lost: 0 bytes in 0 blocks
==29045== possibly lost: 0 bytes in 0 blocks
==29045== still reachable: 192 bytes in 6 blocks
==29045== suppressed: 35,164 bytes in 435 blocks
==29045== Reachable blocks (those to which a pointer was found) are not shown.
==29045== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29045==
==29045== For counts of detected and suppressed errors, rerun with: -v
==29045== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 17)
只需完全删除 main()
中的第二行即可收到与上面相同的输出(Good)。
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
}
同样如此:
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
std::unique_ptr<int> other(ptr.release());
}
祝你好运。
我用unique_ptr
。为了创建这个指针,我使用了这个代码片段:
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); //line 44
}
我在帮助 built-in memory leak checker 的帮助下测试我的项目是否存在内存泄漏。
我得到以下结果:
Detected memory leaks!
Dumping objects ->
my_header.h(44) : {228} normal block at 0x008AD568, 8 bytes long.
Data: < > A0 CB 8A 00 01 00 00 00
my_header.h(44) : {226} normal block at 0x008AD5B8, 8 bytes long.
Data: < > 00 D6 8A 00 00 00 00 00
/////////////////this error repeats many times
此外,我使用 deleaker。这个工具说,没有内存泄漏。
您不应该使用 release()
unless you're handing off the pointer-raw to someone else (hopefully another std::unique_ptr
or a std::shared_ptr
, etc). Instead you should be using reset()
,或者只是让 scope-exit 为您销毁托管对象。
使用您的代码演示好坏的最简单示例:
不好:使用release()
#include <memory>
namespace
{
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
ptr.release();
}
Valgrind 输出
==29012== 4 bytes in 1 blocks are definitely lost in loss record 1 of 87
==29012== at 0x10003B51B: malloc (vg_replace_malloc.c:303)
==29012== by 0x1001CD43D: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==29012== by 0x10000147B: std::__1::unique_ptr<int, std::__1::default_delete<int> > (anonymous namespace)::make_unique<int, int>(int&&) (in ./Sample C++)
==29012== by 0x100001337: main (in ./Sample C++)
==29012==
==29012== LEAK SUMMARY:
==29012== definitely lost: 4 bytes in 1 blocks
==29012== indirectly lost: 0 bytes in 0 blocks
==29012== possibly lost: 0 bytes in 0 blocks
==29012== still reachable: 192 bytes in 6 blocks
==29012== suppressed: 35,164 bytes in 435 blocks
==29012== Reachable blocks (those to which a pointer was found) are not shown.
==29012== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29012==
==29012== For counts of detected and suppressed errors, rerun with: -v
==29012== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)
好:使用reset()
#include <memory>
namespace
{
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
ptr.reset(); // HERE
}
Valgrind 输出
==29045== HEAP SUMMARY:
==29045== in use at exit: 35,356 bytes in 441 blocks
==29045== total heap usage: 508 allocs, 67 frees, 41,216 bytes allocated
==29045==
==29045== LEAK SUMMARY:
==29045== definitely lost: 0 bytes in 0 blocks
==29045== indirectly lost: 0 bytes in 0 blocks
==29045== possibly lost: 0 bytes in 0 blocks
==29045== still reachable: 192 bytes in 6 blocks
==29045== suppressed: 35,164 bytes in 435 blocks
==29045== Reachable blocks (those to which a pointer was found) are not shown.
==29045== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29045==
==29045== For counts of detected and suppressed errors, rerun with: -v
==29045== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 17)
只需完全删除 main()
中的第二行即可收到与上面相同的输出(Good)。
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
}
同样如此:
int main()
{
std::unique_ptr<int> ptr = make_unique<int>(5);
std::unique_ptr<int> other(ptr.release());
}
祝你好运。