Сбой при освобождении памяти - PullRequest
1 голос
/ 13 января 2012

У меня есть приложение, которое используется для изменения содержимого 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);

Я заметил, что всякий раз, когда происходит сбой, значение free (IList[i].PIL_ImageData.PDH_DataPtr.PDH_PathName) не может быть оценено (так говорит отладчик).

Если цикл for закомментирован, сбоя не наблюдается. Пожалуйста, дайте мне знать, в чем может быть проблема.

Ответы [ 2 ]

5 голосов
/ 13 января 2012

Учитывая код, который вы показали, невозможно сказать что-либо о первопричине, потому что:

  • Ваш код не показывает, как было выполнено выделение для указателя с ошибкой.
  • Также он не показывает, где все (может быть много мест) указанный указатель был использован.

Второй вариант немного сложен, потому что указатель мог быть передан n путям управления, где он мог бы снова быть free d или поврежден, и понятно, что здесь невозможно представить все это как часть Вопрос.

Учитывая вышесказанное, лучше всего использовать инструмент профилирования памяти, такой как Valgrind в системах Unix / Linux или Rational Purify В Windows. Как только вы запустите свое приложение с ними, они точно укажут вам причину проблемы.

1 голос
/ 13 января 2012

В дополнение к ответу Алса на использование 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, это только освобождает память, хранящуюся там.Поскольку вы проверяете значение указателя против нуля, чтобы определить, нужно ли его освобождать, не установка указателей на NULL может привести к двойному освобождению, если этот код вызывается дважды (или если что-то находится внутри IList[] точекк структуре, также встречающейся позже в IList[]).

Согласно комментарию, я также убрал проверку на NULL до освобождения (как отмечает Джошуа Грин, free(NULL) совершенно безопасен).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...