c malloc вопросы - PullRequest
       18

c malloc вопросы

1 голос
/ 28 октября 2009

При использовании malloc, если он выдает дамп ядра с ошибкой:

malloc(): memory corruption: ....... ***

Значит ли это, что malloc пытался выделить память, которая не была свободна? Если так, каковы причины этого?

Ответы [ 5 ]

17 голосов
/ 28 октября 2009

Это полностью зависит от вашей реализации malloc, но обычно это означает, что в какой-то момент перед этим malloc что-то записало больше данных в буферизованный буфер, чем его размер.

Многие реализации malloc хранят некоторые свои данные встроенными в свою память, другими словами:

+--------------------------------+
|14 bytes -> Padding             | 
+--------------------------------+
|2 bytes -> Internal malloc info |
+--------------------------------+
|6 bytes -> Your data            |
+--------------------------------+
|8 bytes -> Padding              |
+--------------------------------+
|2 bytes -> Internal malloc info |
+--------------------------------+

Так что, если какой-то ваш код или библиотека записали 16 байтов в этот 6-байтовый буфер, он перезапишет заполнение и 2 байта внутренней информации malloc. В следующий раз, когда вы вызовете malloc, он попытается просмотреть свои данные, чтобы найти место, попасть в перезаписанное пространство, и это будет бессмысленным, поскольку вы перезаписали его, повредив кучу.

В зависимости от реализации такая ошибка также может быть вызвана двойным освобождением.

11 голосов
/ 28 октября 2009

Скорее всего, это не проблема в самом malloc. Скорее, это проблема с вашим приложением, которое изменяет части кучи, чего не должно быть.

Если вы работаете в Linux, попробуйте использовать Valgrind , чтобы узнать, какой код уничтожает вашу кучу.

5 голосов
/ 28 октября 2009

Обычная причина этого заключается в том, что вы перезаписывали данные, которые malloc () не давал вам разрешения перезаписывать - либо переполнение буфера (запись за пределами заданного вами пространства), либо переполнение буфера (запись до запуска буфера).

Иногда это может быть вызвано освобождением указателя, который не был выделен malloc () и др., Или повторным освобождением (двойным освобождением) указателя, который был выделен malloc (). Например, освобождение статического буфера - плохая идея; вы получите коррупцию.

Вы должны предположить, что проблема в вашем коде - это очень маловероятно, чтобы быть проблемой в malloc () и др., И довольно маловероятно, чтобы это было в любой другой используемой вами библиотеке.

2 голосов
/ 28 октября 2009

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

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

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

Использование кучи отладки может быть очень полезно при отладке этих проблем. Компиляторы Microsoft имеют кучу CrtDebug , которая включена в отладочных сборках (но может иметь дополнительные элементы конфигурации). Я не уверен, что GCC имеет из коробки, но есть инструменты, с которыми я знаком, попутно, такие как Valgrind и Electric Fence , которые могут помочь. Наконец, есть тонна самодельных библиотек отладки кучи , которые могут быть полезны (Google вокруг).

1 голос
/ 28 октября 2009

Не могли бы вы предоставить оператор malloc ()?

Кроме того, я хотел дважды проверить, что возвращаемое значение не равно нулю?

Помимо нехватки памяти, которую нужно выделить для начала, проблемы, с которыми я столкнулся при использовании malloc() или new, аналогичны той природе, которую вы упомянули, когда фактически являются результатом поврежденной кучи. Я обычно находил какой-то «интересный» код в другом месте программы, выполняющий что-то вроде memcpy () с символьным буфером, вызывающим переполнение буфера и искаженное адресное пространство.

-bn

...