2009-12-26 1 views
2

에게 할당 실패표준 : : 벡터 예약 방법은 다음과 같이 내 C++에서 응용 프로그램을 버퍼 클래스가 충분한 메모리

class Buffer 
{ 
    public: 
    Buffer(size_t res): _rpos(0), _wpos(0) 
    { 
     _storage.reserve(res); 
    } 

    protected: 
    size_t _rpos, _wpos; 
    std::vector<uint8> _storage; 
} 

때때로 생성자를 사용하여 실패 때문에 필요한 메모리 공간을 할당 할 수 없습니다. 내가 64 비트 응용 프로그램과 같은 GCC 4.4.2 사용이 응용 프로그램을 컴파일 한

#0 0x00007f916a176ed5 in raise() from /lib/libc.so.6 
No symbol table info available. 
#1 0x00007f916a1783f3 in abort() from /lib/libc.so.6 
No symbol table info available. 
#2 0x00007f916a1b33a8 in ??() from /lib/libc.so.6 
No symbol table info available. 
#3 0x00007f916a1b8948 in ??() from /lib/libc.so.6 
No symbol table info available. 
#4 0x00007f916a1bb17c in ??() from /lib/libc.so.6 
No symbol table info available. 
#5 0x00007f916a1bca78 in malloc() from /lib/libc.so.6 
No symbol table info available. 
#6 0x00007f916ac0c16d in operator new (sz=37) 
    at ../../.././libstdc++-v3/libsupc++/new_op.cc:52 
     p = <value optimized out> 
#7 0x00000000004e3d11 in std::vector<unsigned char, std::allocator<unsigned char> >::reserve (this=0x7f911bc49cc0, __n=31077) 
    at /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.4.2/../../../../include/c++/4.4.2/ext/new_allocator.h:89 
     __old_size = 0 
     __tmp = <value optimized out> 

예를 들어, 한 번, res = 37로 생성자를 호출 내가 핵심 덤프에서 가져온 다음과 같은 스택 추적과 세그먼트 폴트를 발생 데비안 5 x64에서 사용하고 있습니다.

도움을 주시면 감사하겠습니다. 감사합니다

+0

흔적은 분명히 당신이 주장하는대로 res = 31077이지 37이 아니라는 것을 보여줍니다. 여전히 작지만 (적어도 64 비트 시스템의 경우) 잘못된 장소에서 오류를 찾고있을 것입니다. 백 트레이스에서 프레임 8 이상을 표시 할 수 있습니까? – Tomek

답변

2

Valgrind를 사용하여 과도한로드로 인해 메모리가 손상된 곳을 찾을 수없는 경우 더 가벼운 솔루션으로 테스트 할 수 있습니다.

Valgrind가 적용되지 않는 서버 응용 프로그램의 경우 (Solaris 8에 플랫폼이 있기 때문에) mpatrol (http://mpatrol.sf.net), 특히 dmalloc (http://dmalloc.com)으로 꽤 좋은 결과를 얻었습니다.

일부는 확장하여 다시 컴파일하지 않고도 사용할 수 있습니다 (dmalloc에 ​​대한 재 링크, mpatrol에 대한 라이브러리 사전로드). 그들은 메모리 사용에 대한 추가 검사를 수행하기 위해 메모리 프리 머 티브를 대체 할 것입니다 (프리미티브에 대한 잘못된 인수, off-by-one 읽기, 힙 손상 ...). 일부 검사는 문제가 발생할 때 정확하게 트리거됩니다 실제 불량 코드보다 약간 나중에 트리거됩니다. 어떤 검사가 활성화되어 있는지 튜닝하고 적용 가능한 경우 검사 빈도를 사용하면 기본 검사를 수행하면서 거의 최고 속도로 실행할 수 있습니다.

"FUNC_CHECK"라고 불리는 dmalloc을 사용하여 다시 컴파일하는 것이 좋습니다. 성능상의 비용으로 버그 스포팅에 많은 정확성을 추가했습니다.

8

segfault가 malloc에 ​​있기 때문에 대부분 다른 코드가 힙을 휴지통에 넣었습니다 (즉, 자신이 소유하지 않고 힙 관리자가 사용하는 메모리 부분에 쓰여졌을 가능성이 큽니다).

Valgrind을 사용하여 어떤 코드가 힙을 삭제하는지 확인하는 것이 좋습니다.

+0

Valgrind는 서버 응용 프로그램이므로이 응용 프로그램에 사용할 수 없으며 부하가 높습니다. Valgrind는 너무 느려서 거의 쓸모 없게됩니다. 그 결과 segfault는 결코 일어나지 않을 것입니다. 불행히도 원인을 찾기 위해 Valgrind 이외의 솔루션이 필요합니다. 어쩌면 내가 응용 프로그램에서 나를 위해 원인을 찾을 수 구현할 수 있습니다. –

+1

@Martin York : 눈치 채지 못했을 경우, 실수없이 코드를 작성하는 방법을 배우려고 노력하고 있습니다. –

+0

눈치 채지 못했을 때, Martin York이 당신을 실수로 찾아 냈습니다. ;) 다른 컴퓨터에서 valgrind를 실행합니다. 궁극적으로, 당신은 많은 선택권이 없습니다. * 어딘가에 * 프로세스에서 일부 코드 조각이 힙을 손상시킵니다 * 여하튼 * 및 * 일부 시간 *이 segfault가 발생하기 전에. 마틴 요크 (Martin York)가 말했듯이, 1) 이러한 버그를 포함하지 않는 코드를 작성하거나 2) Valgrind *와 같은 진단 도구를 실행하여 거기에있는 버그를 찾는 데 도움을 줄 수 있습니다. – jalf

관련 문제