Note that there are some explanatory texts on larger screens.

plurals
  1. POStruggling - yet another memory corruption problem, bad alloc (C++, VS 2008)
    primarykey
    data
    text
    <p>I've read a lot of posts on memory corruption and it seems like it can be a considerably difficult problem to solve. When I run my code on my linux machine it executes fine and valgrind doesn't report any leaks or errors. However when I run the code on my lab's windows machine with VS2008, I get a bad alloc error, stopping with _RAISE(nomem). This seems strange to me because I would have expected valgrind to catch it.</p> <pre><code>void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { // try to allocate size bytes void *p; while ((p = malloc(size)) == 0) if (_callnewh(size) == 0) { // report no memory static const std::bad_alloc nomem; _RAISE(nomem); } return (p); } </code></pre> <p>From what I've read it seems like this problem often comes from writing past the end of an allocated block of memory or after it has been freed but I haven't had any luck identifying where that might be happening. Here's my call stack from after trying to run a Release build.</p> <pre><code>KernelBase.dll!_RaiseException@16() + 0x58 bytes msvcr90.dll!_CxxThrowException(void * pExceptionObject=0x0040f6d4, const _s__ThrowInfo * pThrowInfo=0x6f63d604) Line 161 C++ msvcr90.dll!operator new(unsigned int size=4) Line 63 + 0x17 bytes C++ tempMem.exe!std::vector&lt;unsigned char,std::allocator&lt;unsigned char&gt; &gt;::vector&lt;unsigned char,std::allocator&lt;unsigned char&gt; &gt;(const std::vector&lt;unsigned char,std::allocator&lt;unsigned char&gt; &gt; &amp; _Right=[...]()) Line 500 + 0x31 bytes C++ tempMem.exe!DendriteSegment::DendriteSegment(const DendriteSegment &amp; __that={...}) + 0x4a bytes C++ tempMem.exe!std::list&lt;DendriteSegment,std::allocator&lt;DendriteSegment&gt; &gt;::_Buynode(std::_List_nod&lt;DendriteSegment,std::allocator&lt;DendriteSegment&gt; &gt;::_Node * _Next=0x005d84d0, std::_List_nod&lt;DendriteSegment,std::allocator&lt;DendriteSegment&gt; &gt;::_Node * _Prev=0x0093af50, const DendriteSegment &amp; _Val={...}) Line 1208 C++ tempMem.exe!TP::adaptSegments(Cell * &amp; cellToAdapt=0x005d8450, std::list&lt;segUpdate,std::allocator&lt;segUpdate&gt; &gt; &amp; segUpdateList=[1]({segToUpdate=0x00000000 synapseChanges=[0]() newSynapsesToAdd=[2](0x005bc8f8 {DSlist=[19]({sequenceSegment=true synapse=[3](0x005d79a0 {DSlist={...} connected=0x005d7af8 currentState=0x005d79c0 ...},0x005d7ef8 {DSlist={...} connected=0x005d8050 currentState=0x005d7f18 ...},0x005d8450 {DSlist={...} connected=0x005d85a8 currentState=0x005d8470 ...}) permanence=[3](80 'P',80 'P',80 'P') ...},. ), bool posReinforce=true) Line 701 + 0x1b bytes C++ tempMem.exe!Level::TPlearning() Line 236 + 0x26 bytes C++ tempMem.exe!main(int argc=, char * * argv=) Line 96 C++ msvcr90.dll!_encode_pointer(void * ptr=0x6f5d3607) Line 114 + 0x5 bytes C 0069ee20() msvcr90.dll!_initterm(void (void)* * pfbegin=0x00000001, void (void)* * pfend=0x000a1ef8) Line 903 C tempMem.exe!__tmainCRTStartup() Line 582 + 0x17 bytes C kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes </code></pre> <p>When running a debugging session I get a different error (it doesn't seem to happen all the time though...)</p> <pre><code>return HeapAlloc(_crtheap, 0, size ? size : 1); </code></pre> <p>from here</p> <pre><code>#ifdef _WIN64 return HeapAlloc(_crtheap, 0, size ? size : 1); #else /* _WIN64 */ if (__active_heap == __SYSTEM_HEAP) { return HeapAlloc(_crtheap, 0, size ? size : 1); } else if ( __active_heap == __V6_HEAP ) { if (pvReturn = V6_HeapAlloc(size)) { return pvReturn; } } </code></pre> <p>In this case the call stack is</p> <pre><code> ntdll.dll!_RtlpBreakPointHeap@4() + 0x23 bytes ntdll.dll!@RtlpAllocateHeap@24() + 0x57dbc bytes ntdll.dll!_RtlAllocateHeap@12() + 0x502a bytes ntdll.dll!_RtlDebugAllocateHeap@12() + 0xb5 bytes ntdll.dll!@RtlpAllocateHeap@24() + 0x57c17 bytes ntdll.dll!_RtlAllocateHeap@12() + 0x502a bytes msvcr90d.dll!_heap_alloc_base(unsigned int size=38) Line 105 + 0x28 bytes C msvcr90d.dll!_heap_alloc_dbg_impl(unsigned int nSize=2, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x0052f284) Line 427 + 0x9 bytes C++ msvcr90d.dll!_nh_malloc_dbg_impl(unsigned int nSize=2, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x0052f284) Line 239 + 0x19 bytes C++ msvcr90d.dll!_nh_malloc_dbg(unsigned int nSize=2, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0) Line 296 + 0x1d bytes C++ msvcr90d.dll!malloc(unsigned int nSize=2) Line 56 + 0x15 bytes C++ msvcr90d.dll!operator new(unsigned int size=2) Line 59 + 0x9 bytes C++ tempMem.exe!std::_Allocate(unsigned int _Count=2) Line 43 + 0xc bytes C++ tempMem.exe!std::allocator&lt;uint8_t&gt;::allocate(unsigned int _Count=2) Line 145 + 0x13 bytes C++ tempMem.exe!std::::_Buy(unsigned int _Capacity=2) Line 1115 + 0x14 bytes C++ tempMem.exe!std::::vector(const std::vector&lt;uint8_t, std::allocator&lt;uint8_t&gt; &gt; &amp; _Right=[2](80 'P',80 'P')) Line 501 + 0x2b bytes C++ tempMem.exe!DendriteSegment::DendriteSegment() + 0x8b bytes C++ tempMem.exe!std::_Construct(DendriteSegment * _Ptr=0x007e7490, const DendriteSegment &amp; _Val={...}) Line 52 + 0x97 bytes C++ tempMem.exe!std::allocator&lt;DendriteSegment&gt;::construct(DendriteSegment * _Ptr=0x007e7490, const DendriteSegment &amp; _Val={...}) Line 155 + 0x15 bytes C++ tempMem.exe!std::::_Buynode(std::_List_nod&lt;DendriteSegment, std::allocator&lt;DendriteSegment&gt; &gt;::_Node * _Next=0x00637f60, std::_List_nod&lt;DendriteSegment, std::allocator&lt;DendriteSegment&gt; &gt;::_Node * _Prev=0x00bfcb50, const DendriteSegment &amp; _Val={...}) Line 1199 + 0x47 bytes C++ tempMem.exe!std::::_Insert(std::list&lt;DendriteSegment, std::allocator&lt;DendriteSegment&gt; &gt;::_Const_iterator&lt;1&gt; _Where={sequenceSegment=true synapse=[0]() permanence=[0]() ...}, const DendriteSegment &amp; _Val={...}) Line 718 + 0x65 bytes C++ tempMem.exe!std::::push_back(const DendriteSegment &amp; _Val={...}) Line 670 + 0x6f bytes C++ tempMem.exe!TP::adaptSegments(Cell * &amp; cellToAdapt=0x00637ee8, std::list&lt;segUpdate, std::allocator&lt;segUpdate&gt; &gt; &amp; segUpdateList=[1](...), bool posReinforce=true) Line 701 + 0x16 bytes C++ tempMem.exe!TP::phase3() Line 949 + 0x3e bytes C++ tempMem.exe!Col::TPphase3() Line 398 + 0xd bytes C++ tempMem.exe!Level::TPlearning() Line 236 + 0x4a bytes C++ tempMem.exe!Network::runTPlearning() Line 93 + 0xd bytes C++ tempMem.exe!main(int argc=1, char * * argv=0x006f62a0) Line 93 + 0xd bytes C++ tempMem.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C tempMem.exe!mainCRTStartup() Line 399 C kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes </code></pre> <p>This is my first time debugging this type of problem and I hope I'm just overlooking/misunderstanding something obvious...</p> <p>Here's the code for the adaptSegments function that corresponds to this line from the call stack (Release)</p> <pre><code>tempMem.exe!TP::adaptSegments(Cell * &amp; cellToAdapt=0x005d8450, std::list&lt;segUpdate,std::allocator&lt;segUpdate&gt; &gt; &amp; segUpdateList=[1]({segToUpdate=0x00000000 synapseChanges=[0]() newSynapsesToAdd=[2](0x005bc8f8 {DSlist=[19]({sequenceSegment=true synapse=[3](0x005d79a0 {DSlist={...} connected=0x005d7af8 currentState=0x005d79c0 ...},0x005d7ef8 {DSlist={...} connected=0x005d8050 currentState=0x005d7f18 ...},0x005d8450 {DSlist={...} connected=0x005d85a8 currentState=0x005d8470 ...}) permanence=[3](80 'P',80 'P',80 'P') ...},. ), bool posReinforce=true) Line 701 + 0x1b bytes bool TP::adaptSegments(Cell *&amp; cellToAdapt, std::list&lt;segUpdate&gt; &amp; segUpdateList, bool posReinforce) { std::list&lt;segUpdate&gt;::iterator curSegUpdate; std::list&lt;activeSynapsePair&gt;::iterator curSyn; std::list&lt;Cell *&gt;::iterator synToAdd; int size = 0; //for each segUpdate element in the cell's segUpdateList for (curSegUpdate = segUpdateList.begin(); curSegUpdate != segUpdateList.end(); ++curSegUpdate) { //if the segment already exists if (curSegUpdate-&gt;segToUpdate != NULL) { //if sequence segment flag is true, set it on DS if(curSegUpdate-&gt;sequenceSegment == true) {curSegUpdate-&gt;segToUpdate-&gt;sequenceSegment = true;} if (posReinforce == true) { //for each synapses permanence pair in segUpdate for (curSyn = (curSegUpdate-&gt; synapseChanges.begin()); curSyn !=(curSegUpdate-&gt;synapseChanges.end()); ++curSyn) { //decrement inactive synapses if (curSyn-&gt;second == false) { if (*(curSyn-&gt;first)- permanenceDec &lt; 0) {*(curSyn-&gt;first) = 0;} else {*(curSyn-&gt;first)-= permanenceDec;} } //increment active synapses else if (curSyn-&gt;second == true) { if (*(curSyn-&gt;first)+ permanenceInc &gt; 100) {*(curSyn-&gt;first) =100;} else {*(curSyn-&gt;first)+= permanenceInc;} } } } else if (posReinforce == false) { //for each synapses permanence pair in segUpdate for (curSyn = (curSegUpdate-&gt; synapseChanges.begin()); curSyn !=(curSegUpdate-&gt;synapseChanges.end()); ++curSyn) { //decrement active synapses if (curSyn-&gt;second == true) { if (*(curSyn-&gt;first)- permanenceDec &lt; 0) {*(curSyn-&gt;first) = 0;} else {*(curSyn-&gt;first)-= permanenceDec;} } } } //if adding synapses to an existing segment if (curSegUpdate-&gt;newSynapsesToAdd.empty()==false) { if (curSegUpdate-&gt;segToUpdate-&gt;synapse.size() &lt;MAX_NUM_SYN) { //for each synapses in newSynapses for (synToAdd = curSegUpdate-&gt;newSynapsesToAdd.begin(); synToAdd != curSegUpdate-&gt; newSynapsesToAdd.end(); ++synToAdd) { //add new synapse to list curSegUpdate-&gt;segToUpdate-&gt; synapse.push_back(*synToAdd); //and permenance with initialPerm curSegUpdate-&gt;segToUpdate-&gt; permanence.push_back(initialPerm); } }//if less than MAX_NUM_SYN } }//end if segment already exists //if segment doesn't exist, create a new segment &amp; add synapses else if (curSegUpdate-&gt;segToUpdate == NULL) { size = curSegUpdate-&gt;newSynapsesToAdd.size(); if (size != 0) { DendriteSegment myNewSeg; //create a new DS //set sequenceSegment flag if it is true if (curSegUpdate-&gt;sequenceSegment == true) {myNewSeg.sequenceSegment = true;} std::copy(curSegUpdate-&gt;newSynapsesToAdd.begin(), curSegUpdate-&gt;newSynapsesToAdd.end(), std::back_inserter(myNewSeg.synapse)); myNewSeg.permanence.resize(size, initialPerm); //then add it to the cells list of DS cellToAdapt-&gt;DSlist.push_back(myNewSeg); }//if size not 0 } } return true;} </code></pre> <p>My next step is to try Application Verifier. I tried Intel Inspector XE 2011 but it doesn't seem to detect any relevant memory problems.</p> <p><strong>Update</strong>: Using gflags I found that the cause of my woes was due to having pointers to elements in a std::vector. myVector.push_back(newElem) was used to add elements to the vectors causing pointers to elements in the vector to become bad. I replaced the vectors with std::list which does not have the same problem (see <a href="https://stackoverflow.com/questions/3287801/pointers-to-elements-of-stdvector-and-stdlist">here</a>)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload