Что вызывает ошибку в выделении памяти в узле C ++ STL? - PullRequest
2 голосов
/ 23 декабря 2011

Я написал некоторый код C ++, который прекрасно работает на моем ноутбуке (скомпилирован как компилятором Microsoft, так и g ++ под MinGW). Я в процессе портирования на Unix-машину.

Я скомпилировал как с g ++, так и с ipcp от Intel на Unix-машине, и в обоих случаях моя программа зависала (segfaults) после некоторого запуска. Я могу запустить его на короткое время без сбоев.

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

Не всегда происходит сбой в одном и том же месте кода при каждом его запуске, но всегда происходит во время вызова выделения для создания узла в списке STL. Я не думаю, что у меня заканчивается память. У меня несколько утечек памяти, но они очень маленькие. Что еще может вызвать ошибку выделения памяти? И почему это происходит на Unix-машине, а не на моем ПК?

ОБНОВЛЕНИЕ: я использовал MemoryScape, чтобы помочь отладке. Когда я использовал защитные блоки, программа работала без сбоев, что еще больше указывало на проблему с памятью. Что наконец-то помогло решить проблему, так это «нарисовать» выделенную память. Оказывается, я инициализировал переменную, но не устанавливал ее в значение, прежде чем использовал ее в качестве индекса массива. Поэтому массив был переполнен, потому что он использовал мусор, который был в ячейке памяти переменной - часто это было 0 или какое-то другое небольшое число, так что никаких проблем. Но когда я запускал программу достаточно долго, она с большей вероятностью удерживала большее число и повреждала кучу, когда я записывал за пределы массива. Окрашивание выделенной памяти большим числом вызывало ошибку segfault прямо в строке кода, где я пытался записать значение в массив, и я мог видеть, что большое нарисованное число используется в качестве индекса массива.

Ответы [ 3 ]

3 голосов
/ 24 декабря 2011

Это, вероятно, вызвано повреждением кучи - в других местах кода вы перезаписываете освобожденную память или записываете в память за пределами ваших выделений памяти (переполнение буфера или запись перед началом выделенной памяти).Повреждение кучи обычно приводит к сбоям в несвязанном месте, например в коде STL.Поскольку вы работаете на платформе Unix, вы должны попытаться запустить вашу программу под valgrind, чтобы попытаться определить исходное повреждение кучи.

1 голос
/ 24 декабря 2011

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

Отладчики памяти являются отличными инструментами для выявления таких искажений. valgrind, dmalloc и efence - очень хорошие альтернативы для проверки правильности вашей программы.

0 голосов
/ 24 декабря 2011
 I have a few memory leaks, but they're very small.

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

...