Заставить malloc () возвращать NULL вместо сбоя программы?
Я выделяю память в программе на языке Си с помощью malloc. Это возможно для моей программы выделить больше памяти, чем система имеет место для, и в этот момент программа аварийно завершает работу. Для моих целей было бы лучше, если бы malloc просто вернул NULL (как это, по-видимому, предполагается), так что я могу поймать ошибку. Вместо этого он выдает ошибку, говорящую: "нет памяти, доступной для программы сейчас: небезопасно вызывать malloc.- И программа выходит из строя.
Как я могу исправить вот это?
Edit: я знаю, что программа падает сама по себе, а не потому, что я пытаюсь ссылаться на нулевой указатель. Программа никогда напрямую не вызывает malloc, но вместо этого вызывает функцию, которую я написал, которая вызывает malloc, а затем проверяет, возвращает ли она NULL. Он никогда не говорит, что malloc вернулся NULL.
Edit 2: Если это полезно, вот полный вывод ошибок:
Программа получила сигнал: "EXC_BAD_ACCESS".
sharedlibrary применять нагрузки-правила все
предупреждение: невозможно восстановить ранее выбранный кадр.
Формататоры данных временно недоступны, повторите попытку после "продолжить". (Отлаживаемая программа сигнализировала, находясь в функции, вызываемой из GDB.
GDB остается в кадре, где был получен сигнал.
Чтобы изменить это поведение, используйте "set unwindonsignal on"
Вычисление выражения, содержащего функцию (dlopen), будет отменено.)
Нет памяти, доступной для программирования сейчас: небезопасно вызывать malloc
5 ответов:
Как только вы строчите в куче через переполнение буфера, дикие указатели или другие ошибки, поведение Мэллока становится неопределенным, и он может вернуть что угодно.
Мэллок - это просто библиотека пользовательского пространства, в ней нет никакой магии. Если я нацарапаю весь связанный список имен клиентов вашего приложения, вы получите странное поведение, когда позже получите доступ к этому списку. Мэллок ведет себя точно так же, но поскольку использование Мэллок распространяется через код, причина и следствие имеют глобальный охват.Все ответы танцуют вокруг того факта, что ошибки указателей являются единственным наиболее распространенным источником дефектов в C-коде. Вам повезло, что вы получаете SIGBUS, который является свидетельством дефекта, который может быть широко отделен от места и времени возникновения неисправности. Используйтеvalgrind , чтобы помочь вам найти, где находится настоящий дефект.
Он проверяет, возвращает ли Malloc NULL? У вас могут возникнуть проблемы с тестом на равенство. Попробуйте что-нибудь вроде 'if (malloc(...)) затем ... все остальное ...; "а не конкретный чек.
Если это не поможет, то запустите только препроцессор и выясните, что NULL "редактируется".
Согласно этой странице apple, программа прервется на основе ошибки malloc, если переменная окружения
MallocErrorAbortвключена в xcode. Чтобы отключить эту переменную, щелкните правой кнопкой мыши на исполняемом файле в виде дерева, выберите " получить информацию "и перейдите на вкладку" Аргументы".
Странно ... следующее работает для меня, если я компилирую его из командной строки. Среда выполнения, поставляемая
malloc, имеет множество опций, как упоминал Спенсер. Если вы используете XCode, я бы искал опцию, которая управляет этим.#include <limits.h> #include <stdio.h> #include <stdlib.h> int main() { signed long long alloc_sz = (1 * 1024 * 1024 * 1024); while (alloc_sz > 0ull) { char *ptr = malloc(alloc_sz); if (ptr == NULL) { fprintf(stderr, "failed to allocate %llu bytes\n", (unsigned long long)alloc_sz); break; } else { free(ptr); fprintf(stderr, "allocated %llu bytes\n", (unsigned long long)alloc_sz); } alloc_sz *= 2ull; } return 0; }кстати: это в debug илиrelease build? Возможно, XCode пытается как-то помочь вам.
Как уже говорили другие, очень вероятно, что вы перезаписали какое-то внутреннее состояние
malloc's, заставляя его делать странные вещи.В Linux способ, которым вы могли бы отследить это, состоял бы в использовании
valgrind. Если ваш код достаточно кроссплатформенен, чтобы вы могли запустить его на Linux (возможно, в виртуальной машине), я бы рекомендовал сделать это.Если эта опция недоступна, Mac OS X имеет свои собственные встроенные средства отладки. На высоком уровне есть инструменты. На более низком уровне,
mallocбудет включить отладку в ответ на определенные переменные среды: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/malloc.3.html Прокрутите вниз до разделаENVIRONMENT. Например, вы можете запустить свою программу с помощьюMallocGuardEdges=1 ./myProgВы также можете использовать
libgmalloc, что похоже на функции отладкиmallocна crack. Вы можете прочитать об этом здесь: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/libgmalloc.3.htmlВы бы запустили свою программу так:
DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib ./myProg
Comments