2017-01-31 3 views
0

У меня есть эта программа, которая хранит много вещей в памяти через указатели на области памяти (структуры, массивы) и этот пользователь, который может запустить программу в любое время. После init программа должна освободить ранее используемую память (если она есть, и это улов) и выделить новое хранилище с возможным разным размером.Свободная память в C: как проверить действительный указатель?

Теперь, начиная с самого первого init, я понятия не имею, на что указывают мои указатели: особенно, я не знаю, являются ли они мусором или нет. Но в случае, если это не так, мне нужно освободить то, на что они указывают. Откуда мне знать?

+3

Вы просто не можете. – George

+0

@George Я так боялся. Идея только что появилась у меня в голове: отделите первый init только с mallocing и no freeing - поскольку система только что началась, и это первый раз и все - от дальнейших действий, которые я буду называть «reinits», и которые будут знать, что они приходят после предыдущего malloc и что они могут освободить то, что стоит за указателями и malloc снова. Stackoverflow иногда дает ответы через вдохновение, а не через других людей ... – Charles

+0

Вы должны делать «бухгалтерию» указателей. Всякий раз, когда что-то больше не нужно, освободите его и установите указатель на нуль. Затем после инициализации все, что не пусто, является допустимым указателем, который должен быть освобожден. –

ответ

3

За исключением того, что указатель, указывающий на NULL, не указывает ни на что, нет способа проверить, указывает ли данный указатель на что-то действительное. Это ваша работа, чтобы отслеживать указатели, которые все еще указывают на динамическую память. (Указатели могут указывать на автоматический и static переменные и, конечно, вы должны не попытка free этого.)

Много народа установить указатель на NULL, когда они имеют free d соответствующую память и рассчитывать на то, что C определяет free(NULL) как нет-op. Поэтому вы можете принять такой подход.

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

Или вы могли бы построить себе одну из них: https://en.wikipedia.org/wiki/Boehm_garbage_collector

+1

Общепринятой и совершенно безопасной практикой является такой код, как, например, 'static int * ptr = NULL;' ... 'void create_stuff (void) {free (ptr); ptr = malloc (...)} '...' void cleanup (void) {free (ptr); ptr = NULL; } '. Это означает, что эти функции можно вызывать в любое время, в любом порядке, а также несколько раз на протяжении всего выполнения.Это обеспечивает большую гибкость при создании и уничтожении объектов, и код всегда находится в безопасном состоянии. Один и тот же «шаблон дизайна» также может использоваться для других видов ресурсов, таких как ручки потоков, ручки файлов и т. Д. Вся хорошая практика, ничто не пахнет ею. – Lundin

+0

Точка взята. Я немного смягчил предостерегающую историю. Но не используйте 'NULL' в качестве предлога для написания неаккуратного кода. – Bathsheba

3

мы говорим о глобалов здесь? Потому что они автоматически инициализируются до нуля. В общем, ваша программа должна быть написана таким образом, что указатели никогда не указывают на мусор, но либо в действительных данных, либо имеют значение NULL (free(NULl) - это не-op).

+0

Да, файловая область, но это не имеет значения. http://stackoverflow.com/questions/13251083/the-initialization-of-static-variables-in-c – Charles

Смежные вопросы