[英]Possible memory leak with malloc, struct, std::string, and free
[英]c++ memory error when using malloc/realloc/free on std::string
我寫了這樣一小段代碼:
template <class T>
void
test()
{
T* ptr = nullptr;
ptr = (T*)malloc(1 * sizeof(T));
new ((void*)ptr) T(T());
ptr = (T*)realloc(ptr, 2 * sizeof(T));
new ((void*)(ptr + 1)) T(T());
(ptr)->~T();
(ptr + 1)->~T();
free(ptr);
}
struct foo
{
foo() : ptr(malloc(10)) {}
~foo() { free(ptr); }
void* ptr;
};
int
main()
{
test<int>(); // this is ok
test<foo>(); // this is ok
test<std::string>(); // memory error :(
return 0;
};
當T為[int]或[foo]時,一切正常。 但是將[std :: string]用作T會使valgrind報告如下內存錯誤:
==18184== Memcheck, a memory error detector
==18184== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18184== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==18184== Command: ./a.out
==18184==
==18184== Invalid free() / delete / delete[] / realloc()
==18184== at 0x4C2C20A: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18184== by 0x401074: void test<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >() (tmp.cpp:26)
==18184== by 0x400CFC: main (tmp.cpp:44)
==18184== Address 0x5a89e70 is 16 bytes inside a block of size 32 free'd
==18184== at 0x4C2CC37: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18184== by 0x401042: void test<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >() (tmp.cpp:22)
==18184== by 0x400CFC: main (tmp.cpp:44)
==18184== Block was alloc'd at
==18184== at 0x4C2AB8D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18184== by 0x40100F: void test<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >() (tmp.cpp:18)
==18184== by 0x400CFC: main (tmp.cpp:44)
==18184==
==18184==
==18184== HEAP SUMMARY:
==18184== in use at exit: 0 bytes in 0 blocks
==18184== total heap usage: 9 allocs, 10 frees, 72,856 bytes allocated
==18184==
==18184== All heap blocks were freed -- no leaks are possible
==18184==
==18184== For counts of detected and suppressed errors, rerun with: -v
==18184== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
為什么只有[std :: string]會導致內存問題,而[foo]在ctor和dtor中也都有malloc / free?
我正在使用g ++ 6.2.1和valgrind 3.12.0
malloc()
, free()
和realloc()
是C庫函數,它們對C ++類,其構造函數和析構函數絕對一無所知。
您正在使用malloc()
和new
放置,以使用malloc
分配的內存構造std::string
。 這可以。
但是然后,您正在使用realloc()
重新分配已分配的內存。
在內存中復制/移動C ++對象必須使用相應對象的復制/移動構造函數來完成。 無法使用realloc()
復制/移動內存中的C ++對象。
做到這一點的唯一方法是malloc()
一個新的內存塊,使用placement new
調用對象的復制/移動構造函數,以便將它們復制/移動到新的內存塊中,最后調用對象的析構函數。舊的內存塊,之后可以對其進行free()
ed。
realloc
與非POD類型不兼容。
因為它可以在不移動的對象意識到的情況下移動內存中的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.