Heap corruption: What could the cause be?

后端 未结 13 1457
时光取名叫无心
时光取名叫无心 2020-12-25 12:56

I am investigating a crash due to heap corruption. As this issue is non-trivial and involves analyzing the stack and dump results, I have decided to do a code review of file

相关标签:
13条回答
  • 2020-12-25 13:19

    Every time you do something which isn't defined in the language standard, it is undefined behavior, and one of the ways in which it might manifest itself is through heap corruption. There are about three million ways to do this in C++, so it's really impossible to say.

    A few common cases are double-freeing dynamically allocated memory, or writing outside the bounds of an array. Or writing to an uninitialized pointer.

    Recent versions of Microsoft's compiler add an /analyze compiler switch which performs a bunch of static analysis to catch such errors. On Linux, valgrind is an obvious choice.

    Of course, you are using VC6 which has been unsupported for years, and which has a number of known bugs, resulting in invalid code being generated.

    If possible, you should upgrade to a proper compiler.

    0 讨论(0)
  • 2020-12-25 13:28

    There are products that will observe the memory allocations and deallocations, and produce a report on anomalies. Last I used one, they weren't cheap, but I don't know what the situation is right now. However, finding stuff for VC++ 6 might be a problem.

    Remember that you're liable to be getting heap corruption a lot more often than you're going to crash, so be attentive to the problem reports, and fix all heap corruption.

    I'd suggest using std::tr1::smart_ptr<> instead of raw pointers everywhere, but I'm not sure VC++ 6 is going to support that.

    Why are you still on VC++ 6? Would it be practical to upgrade? The tools are better with the more recent versions, and they fully support smart pointers.

    0 讨论(0)
  • 2020-12-25 13:28

    An additional debugging tip is to look at the values that are being written to the wrong place using the raw memory view. Is it writing zeros... strings... some other recognizable number pattern? If you can see the corrupted memory at some point after the error occurs, that can provide a hint of the code that caused it.

    Also always set pointers to null after deleting them even in destructors. Sometimes unexpected things can be triggered during a destructor chain in a base class than cause an access to a partially deleted sub-class.

    0 讨论(0)
  • 2020-12-25 13:28

    During freeing heap memory, first child memory block need to be deleted and then parant memory block otherwise the child momory block would be leaked parmanently which causes the crash after running the tool millions of times.. ex:

    constQ= new double* [num_equations];
    for(int i=0;i<num_equations;i++)
    {
    constQ[i]=new double[num_equations];
    for(int j=0;j<num_equations;j++)
    {
    constQ[i][j]=0.0;
    }
    .
    .
    .
    
    //Deleting/Freeing memory block 
    //Here the below only parent memory block is deleted, the child memory block is leaked.
    
    if(constQ!=NULL)
    {
    delete[] constQ;
    constQ=NULL
    } 
    //Correct way of deleting heap memory..First delet child block memory and then Parent block
    
    if(constQ!=NULL)
    {
    for(int i=0; i <num_equations;i++)
    {
    delete[] constQ[i];
    delete[] constQ;
    constQ=NULL
    }
    
    0 讨论(0)
  • 2020-12-25 13:29

    You can look at the sample chapter from the Advanced Windows Debugging book which provides various examples of heap corruption.

    EDIT: If you are using stl containers which might move elements during changes (i.e. vector, deque), ensure that you are not keeping references into such elements across operations which might changes it.

    0 讨论(0)
  • 2020-12-25 13:32

    Its a common mistake to free() or delete allocated memory more than one. It may help to insert something like *var = NULL after such calls, and to check for != NULL when calling free. Although in C++ its legal to call delete with a NULL variable, calling C - free() will fail.

    Also a common problem is to confuse delete and delete [].

    Variables allocated with new must be released with delete.

    Array allocated with new [] must be released with delete[].

    Also make sure not to mix C- style memory management (malloc, calloc, free) with C++ style memory management (new/delete). In legacy code often both are mixed, but things allocated with the one can not be freed with the other.

    All of these errors will usually not be recognized by a compiler.

    0 讨论(0)
提交回复
热议问题