2012-01-13 118 views
1

我有一個用於修改pdf文件內容的應用程序。一旦做出所需的更改,我將保存該文件並退出應用程序。在這個過程中,我想清除已分配給PDF文件的內存。代碼如下:釋放內存時崩潰

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是一個數據結構來保存有關該文件的信息。 PDH_Pathname是pdf的詳細信息存儲的臨時目錄。

我的應用程序崩潰始終在

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

我注意到,每當它崩潰,免費(IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName)價值無法評估(這就是調試器說的話)。

如果for循環被註釋掉,則沒有觀察到碰撞。請讓我知道可能是什麼問題。

+1

您可以發佈您在哪裏以及多少次分配這些資源:/ – codekiddy 2012-01-13 05:16:41

+0

您已標記此C++,但代碼調用了'free' :( – 2012-01-13 05:21:11

+0

對不起。這部分代碼位於C – Darzen 2012-01-13 05:22:29

回答

1

除了阿爾斯答案Valgrind的使用,它可能是值得你的指針設置爲NULL你釋放他們之後:

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()不設置指針NULL,它只是釋放內存存儲在那裏。由於您正在測試指針的值,以確定是否需要釋放它,所以如果此代碼被調用兩次(或者如果IList[]內的任何內容也指向一個結構,則不會將指針設置爲NULL)稍後在IList[]中遇到)。

根據評論,我也刪除了免費之前檢查NULL(如約書亞格林指出,free(NULL)是完全安全的)。

+1

沒有任何理由在釋放它之前測試一個針對NULL的指針 - free(NULL)是一個NOP。 「免費」之後將其設置爲「NULL」當然是最安全的策略。 – 2012-01-13 06:24:55

+0

@JoshuaGreen好點,更新:) – 2012-01-14 02:30:26

5

既然你已經證明它的代碼是不可能說的根源任何東西,因爲:

  • 您的代碼並不顯示配置是如何在斷層指針完成。
  • 它也沒有顯示所述指針在哪裏使用(可能有很多地方)。因爲指針可能已被傳遞到n個控制路徑,其中也可能是free一下d

第二個是有點麻煩或遭破壞,可以理解這是不可能提供所有的,在這裏作爲一個部分問題。

鑑於上述情況最好的辦法是使用內存分析工具,如在Unix/Linux系統Valgrind的的Rational Purify的在Windows上。一旦你使用這些應用程序運行你的應用程序,他們就會明確指出問題的根源。