2016-11-05 8 views
0

나는 다음과 같은 코드의 작은 조각을 썼다 : T는 [INT] 또는 [푸] 인 경우C++ 메모리 오류 사용의 malloc 표준에/realloc을/무료 : 문자열

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; 
}; 

은 모든 것이 잘 작동합니다. [푸] 또한 모두의 ctor에서의 malloc/무료 [표준 : : 문자열] 동안 메모리 문제로 연결 왜에만

==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) 

있다

: 그러나 [표준 : : 문자열] T는 다음과 같이 메모리 오류를보고 Valgrind의 원인으로를 사용하여 & dtor?

나는 ++ 3.12.0

답변

3

malloc() 6.2.1 및 Valgrind의, free()을 g을 사용하고, 그리고 realloc()는 C++ 클래스, 자신의 생성자와 소멸자 대해 아무것도 알지 C 라이브러리 함수입니다.

malloc()에 배치 new을 사용하면 malloc -ed 메모리를 사용하여 std::string을 구성합니다. 이건 괜찮아.

그러나 그렇다면 realloc()을 사용하여 할당 된 메모리를 재 할당하고 있습니다.

메모리에서 C++ 객체 복사/이동은 해당 객체의 복사/이동 생성자를 사용하여 수행해야합니다. realloc()을 사용하여 메모리에있는 C++ 객체를 복사/이동하는 것은 불가능합니다.

이 작업을 수행 할 수있는 유일한 방법은 malloc()에 복사/새 메모리 블록로 이동, 마지막의 소멸자를 호출하기 위해 객체의 복사/이동 생성자를 호출 할 수있는 새로운 메모리 블록 사용 배치 new입니다 예전 메모리 블록에있는 객체들. 그 후에는 free() -ed가 될 수있다.

2

realloc은 비 POD 유형과 호환되지 않습니다.

이동 된 개체가 인식하지 못하면 메모리에서 항목을 이동할 수 있기 때문에