как освободить память, выделенную с помощью malloc? - PullRequest
1 голос
/ 22 марта 2011
 struct element {
   unsigned long int  ip;
   int type;
   int rtt;
   struct element * next;
   struct element * edge;
};

У меня есть связанный список. Я создаю новые узлы, используя malloc. Я попытался освободить память, используя свободный но когда я снова запускаю функцию перемещения, я могу пройти по связанному списку, и значение rtt является правильным, а также указатели следующего и ребра, так как я могу следовать за связанным списком. ТОЛЬКО значение ip повреждено. почему это?

Ответы [ 4 ]

7 голосов
/ 22 марта 2011

Поведение malloc() и free() сильно зависит от операционной системы и используемой вами библиотеки Си. В большинстве реализаций фактически есть два распределителя памяти в игре:

  • Распределитель памяти ОС, который использует средства виртуальной памяти процессора для обеспечения процесса собственным адресным пространством и отображает страницы физической памяти в это адресное пространство для использования.

  • Распределитель памяти библиотеки C, который на самом деле является частью кода приложения и использует страницы, предоставляемые ОС, для обеспечения детализированных средств управления памятью, как предусмотрено malloc() и free().

Как правило, вызов free() выполняет одно или несколько из следующих действий:

  • Помечает указанную область памяти как свободную в распределителе памяти C. Это позволяет повторно использовать эту память. free() не обнуляет освобожденную память.

  • Это может вернуть память в ОС, в зависимости от настроек распределителя памяти C и того, возможно ли вообще освободить эту часть кучи. Если память не возвращается в ОС, она может быть повторно использована будущими вызовами malloc() тем же приложением.

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

  • Память возвращена ОС, и ваша программа, как правило, вылетает. Если вы спросите меня, это, вероятно, лучший сценарий - у вас есть проблема, конечно, но вы ее знаете .

  • Память не была повторно использована, поэтому ваши старые данные все еще там. Ваша программа продолжается, как будто ничего не случилось. Это на мой взгляд худший вариант развития событий. Похоже, ваш код работает правильно, и, если Мерфи имеет право голоса, он будет продолжать действовать до тех пор, пока не достигнет ваших конечных пользователей - , а затем он будет впечатляющим.

  • Память была повторно использована вашей программой, и ваш код начнет возиться с собственными данными. Если вы осторожны (и удачливы?), Вы, вероятно, заметите, что результаты выключены. Если нет, хорошо ...

Если вы работаете в Linux / Unix Valgrind - хороший инструмент для решения проблем управления памятью, подобных этой. Существуют также библиотеки замены для распределителя памяти C, такие как DUMA , которые также позволяют обнаруживать такие проблемы.

1 голос
/ 22 марта 2011

Освобождение памяти освобождает ее для повторного использования. Это не обязательно уничтожает данные, которые были в этом месте. Вы не должны обращаться к области памяти, которая была освобождена, поскольку поведение не определено (то есть обычно очень плохо).

Если вы хотите уничтожить данные по какой-то странной причине, перезапишите область памяти перед ее освобождением (например, memset(buf, 0, len)).

1 голос
/ 22 марта 2011

Память не стирается при ее освобождении - это было бы пустой тратой процессорного времени. Он просто размещен в «свободном списке». Вот почему ваши данные все еще там

Всякий раз, когда вы освобождаете блок, вы должны установить соответствующий указатель в NULL, чтобы вы случайно не ссылались на него - он может быть использован повторно в любое время.

1 голос
/ 22 марта 2011

На самом деле free ничего не удаляет, он просто сообщает ОС, что может снова использовать эту память, например, когда вы в следующий раз вызовете malloc (), он может перезаписать некоторые из ваших узлов.

...