Darzen
Darzen

Reputation: 1165

Crash while freeing memory

I have an application which is used to modify content of a pdf file. Once the required changes are made , i save the file and quit the application. During this process i would like the clear the memory that has been assigned to the pdf file. The code is as given below:

    for (i32 i = 0; i < job_state->PDF_IList_len; i++) {
        if(IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName)
            free (IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName);
        if(IList[i].PIL_DependentImages)
            free (IList[i].PIL_DependentImages);
    }
    job_state->PDF_ImageList = NULL;
    job_state->PDF_context = NULL;
    free (IList);

job_structure is a data structure to save info about the file. PDH_Pathname is the temp directory where the details of the pdf is stored.

My application always crashes at

free (IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName);

I have noticed that whenever it crashes,the value for free (IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName) cannot be evaluated(thats what the debugger says).

If the for loop is commented out, there is no crash observed. Please let me know what can be the issue.

Upvotes: 1

Views: 2034

Answers (2)

Timothy Jones
Timothy Jones

Reputation: 22145

In addition to Als' answer to use valgrind, it's probably worth setting your pointers to NULL after you've freed them:

for (i32 i = 0; i < job_state->PDF_IList_len; i++) {
    free (IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName);
    IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName = NULL;
    free (IList[i].PIL_DependentImages);
    IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName = NULL;        
}

free() doesn't set pointers to NULL, it only releases the memory stored there. Since you're testing the value of the pointer against zero to determine whether it needs to be freed, not setting the pointers to NULL could be causing a double free if this code is called twice (or if anything inside IList[] points to a structure also encountered later in the IList[]).

As per a comment, I've also removed the check against NULL before the free (as Joshua Green points out, free(NULL) is perfectly safe).

Upvotes: 1

Alok Save
Alok Save

Reputation: 206596

Given the code that you have shown it is not possible to say anything about the root cause because:

  • Your code does not show how the allocation was done on the faulting pointer.
  • Nor does it show where all(could be lot many places) the said pointer was used.

The second one is a bit tricky because the pointer could have been passed to n control paths where it could be freed again or gets corrupted and understandably it is impossible to provide all of that in here as a part of the Question.

Given the above your best bet is to use a memory profiling tool like Valgrind on Unix/Linux systems or Rational Purify On Windows. Once you run your application with these, they will exactly point you out the root cause of the issue.

Upvotes: 5

Related Questions