Подтвердить что ты не робот

Стратегия отладки, чтобы найти причину bad_alloc

У меня есть довольно серьезная ошибка в моей программе - случайные вызовы new() throw bad_alloc.

Из документации, которую я могу найти на bad_alloc, кажется, это брошено по следующим причинам:

  • Когда на компьютере заканчивается память (что определенно не происходит, у меня 4 ГБ ОЗУ, программа бросает bad_alloc при использовании менее 5 МБ (отмечена в диспетчере задач), при этом ничего не работает в фоновом режиме).

  • Если память становится слишком фрагментированной, чтобы выделять новые блоки (что, опять же, маловероятно), блок размером с наибольший размер, который я когда-либо выделял, был бы около 1 КБ, и это не будет сделано более 100 раз перед сбоем имеет место).

Основываясь на этих описаниях, у меня действительно нет нигде, где можно было бы вызвать bad_alloc.

Тем не менее, приложение, которое я запускаю, запускает более одного потока, что может помочь в решении этой проблемы. Проверяя все объекты в одном потоке, все работает нормально. Единственное, что я могу подумать об этом, это может быть какое-то гоночное условие, вызванное вызовом new() в нескольких местах одновременно, но я попытался добавить мьютексы, чтобы предотвратить это поведение никакого эффекта.

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

Я использую Microsoft Visual Studio 2008 с Poco для потоковой передачи.

4b9b3361

Ответ 1

Другая возможная проблема заключается в том, что, хотя вы отмечаете, что программа использует менее 5 МБ, вы не указываете, сколько места она пытается выделить. У вас может быть какое-то условие гонки, которое искажает значение, которое вы используете для определения размера распределения, и оно может пытаться выделить 37 ТБ или что-то бессмысленное.

Не особенно вероятно, я полагаю, но стоит проверить.

Ответ 2

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

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

Кроме того, следует отметить, что 32-разрядный процесс в Windows имеет не более 2 ГБ адресного пространства (3 ГБ для программ с большим адресом). Это независимо от того, сколько оперативной памяти вы установили, память виртуальная, а распределение не прерывается, пока вы не исчерпали адресное пространство, даже если у вас всего 1 ГБ ОЗУ.

Вот хорошее обсуждение повреждения памяти в С++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm

Ответ 3

Несколько пояснений:

Каждый процесс в окнах получает 4 ГБ виртуальной памяти, из которых 2 ГБ для пользовательского пространства и остается для пространства ядра. 4 ГБ оперативной памяти не будет вносить вклад в виртуальную память, но она предназначена для физической памяти.

В памяти 2 ГБ загружаются все EXE, DLL и почти 1,6 - 1,7 ГБ для распределения памяти. В этой памяти, если для выделения нет смежной памяти, выделение памяти не выполняется.

Ответ 4

bad_alloc может быть брошен и другим кодом.

Я видел, что он использовался ограниченным пулом памяти, предназначенным для использования с контейнерами STL. Когда предел размера был поражен, он бросил bad_alloc, и программное обеспечение просто должно было его обработать.

Ответ 5

У меня была эта проблема раньше, и она была исправлена ​​путем очистки и восстановления проекта. Всегда стоит попробовать, когда у вас странное поведение (если только это не огромный проект, требующий много времени для компиляции).