Почему не освобождает (), обнуляют память до выпуска его?

Посмотрите на мой плагин для разработки приложения колебания. Это столь же легко как тот из netbeans': http://code.google.com/p/visualswing4eclipse/

5
задан Shog9 20 August 2009 в 22:21
поделиться

14 ответов

Обнуление блока памяти при его освобождении потребует дополнительного времени. Поскольку большую часть времени в этом нет необходимости, по умолчанию это не делается.

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

23
ответ дан 18 December 2019 в 05:11
поделиться

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

0
ответ дан 18 December 2019 в 05:11
поделиться

Потому что это будет пустой тратой времени.

0
ответ дан 18 December 2019 в 05:11
поделиться

Если вы хотите, чтобы память была установлена ​​на 0, когда вы ее освобождаете, вам придется сделать это самостоятельно , прежде чем вы free () Это. Если вы попробуете после free () , нет никаких гарантий, что он не был выделен снова. Например, для этого можно использовать memset () .

free () не гарантирует, что память будет очищена, потому что C не гарантирует, что malloc () вернет инициализированную память. В любом случае вы должны инициализировать его самостоятельно после того, как он был выделен, поэтому нет смысла очищать его, когда он free () 'd

6
ответ дан 18 December 2019 в 05:11
поделиться
memset(ptr, 0, size);
free(ptr);

Думаю, ты хочешь это ...

5
ответ дан 18 December 2019 в 05:11
поделиться

C почему в свободной реализации память явно не установлена ​​в ноль.

Из-за скорости.

Потому что после того, как мы освободим память, как мы обнуляем ее после освобождения.

Э?

6
ответ дан 18 December 2019 в 05:11
поделиться

[Изменить: это попытка чтобы ответить на вопрос автора. Вопрос мог быть или не был изменен редактированием shog9 - трудно сказать, поскольку оригинал был неясен ...]

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

Но я предполагаю, что когда вы говорите «мы устанавливаем его в ноль после освобождения», вы, возможно, имеете в виду такой код:

free(ptr);
ptr = NULL;

Если это так, то причина, по которой free не может установить ptr в NULL, заключается в том, что free получает значение только из переменной ptr. У него нет возможности изменить ptr, потому что вы не передаете саму переменную ptr в free. Вы просто передаете адрес, который в настоящее время хранится в нем. Это часть дизайна языка C - когда вы вызываете функцию, передающую значение, вызываемый объект не может сказать, как было вычислено это значение, или какая переменная может содержать его в коде вызывающего. Сделать исключение из этого правила языка просто бесплатно было бы безумием, даже если бы это было возможно.

В любом случае, не все обнуляют указатели после их освобождения. Некоторые люди думают, что это хорошая мера безопасности, другие думают, что это не так. Что бы вы об этом ни думали, код не обнуляет память, он обнуляет только указатель на память. Если вы хотите написать функцию, которая очищает указатель, вы можете:

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Затем использовать ее так:

free_and_clear(&ptr);

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

Некоторые люди думают, что это хорошая мера безопасности, другие думают, что это не так. Что бы вы об этом ни думали, код не обнуляет память, он обнуляет только указатель на память. Если вы хотите написать функцию, которая очищает указатель, вы можете:

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Затем использовать ее так:

free_and_clear(&ptr);

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

Некоторые люди думают, что это хорошая мера безопасности, другие думают, что это не так. Но что бы вы об этом ни думали, код не обнуляет память, он обнуляет только указатель на память. Если вы хотите написать функцию, которая очищает указатель за вас, вы можете:

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Затем использовать ее так:

free_and_clear(&ptr);

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

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Затем используйте его так:

free_and_clear(&ptr);

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

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Затем используйте его так:

free_and_clear(&ptr);

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

6
ответ дан 18 December 2019 в 05:11
поделиться

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

2
ответ дан 18 December 2019 в 05:11
поделиться

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

Однако это далеко не ответ на то, чего пытается достичь OP. Во-первых, обнуление памяти на 100% бесполезно для защиты вашего приложения. Даже если страница памяти выделена другому запущенному процессу, в большинстве операционных систем эта процедура не является детерминированной, и ни один здравомыслящий хакер НИКОГДА не будет использовать такую ​​технику для компрометации ваших данных.

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

Чтобы действительно ответить на ваш вопрос. Если вы пытаетесь защитить некоторые конфиденциальные данные внутри своей программы на C, вы попадаете в область, которая намного превосходит обычных программистов C / C ++ (таких как я), в область написания виртуальных машин для выполнения ваших операций с конфиденциальными данными.

Тот факт, что вы даже задаете этот вопрос, означает, что с вашей стороны было бы безрассудно разрабатывать что-то, что требует такого уровня защиты. Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

)) наш гипотетический хакер просто доберется до данных до того, как произойдет memset.

Чтобы действительно ответить на ваш вопрос. Если вы пытаетесь защитить некоторые конфиденциальные данные внутри своей программы на C, вы попадаете в область, которая намного превосходит обычных программистов C / C ++ (таких как я), в область написания виртуальных машин для выполнения ваших операций с конфиденциальными данными.

Тот факт, что вы даже задаете этот вопрос, означает, что с вашей стороны было бы безрассудно разрабатывать что-то, что требует такого уровня защиты. Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

)) наш гипотетический хакер просто доберется до данных до того, как произойдет memset.

Чтобы действительно ответить на ваш вопрос. Если вы пытаетесь защитить некоторые конфиденциальные данные внутри своей программы на C, вы попадаете в область, которая намного превосходит обычных программистов C / C ++ (таких как я), в область написания виртуальных машин для выполнения ваших операций с конфиденциальными данными.

Тот факт, что вы даже задаете этот вопрос, означает, что с вашей стороны было бы безрассудно разрабатывать что-то, что требует такого уровня защиты. Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

Если вы пытаетесь защитить некоторые конфиденциальные данные внутри своей программы на C, вы попадаете в область, которая намного превосходит обычных программистов C / C ++ (таких как я), в область написания виртуальных машин для выполнения ваших операций с конфиденциальными данными.

Тот факт, что вы даже задаете этот вопрос, означает, что с вашей стороны было бы безрассудно разрабатывать что-то, что требует такого уровня защиты. Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

Если вы пытаетесь защитить некоторые конфиденциальные данные внутри своей программы на C, вы попадаете в область, которая намного превосходит обычных программистов C / C ++ (таких как я), в область написания виртуальных машин для выполнения ваших операций с конфиденциальными данными.

Тот факт, что вы даже задаете этот вопрос, означает, что с вашей стороны было бы безрассудно разрабатывать что-то, что требует такого уровня защиты. Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

Кроме того, это не будет первой остановкой в ​​защите ваших данных. Сначала выберите низко висящий фрукт, и в Интернете есть много информации об этом.

2
ответ дан 18 December 2019 в 05:11
поделиться

Очень конкретный ответ на вопрос «Почему память не устанавливается на 0 после ее освобождения?» это «Поскольку спецификация языка не определяет такое поведение.

Из черновика спецификации ANSI C:« Свободная функция заставляет пространство, на которое указывает ptr, быть освобождается, то есть становится доступным для дальнейшего распределения "

2
ответ дан 18 December 2019 в 05:11
поделиться

free () не освобождает память обратно в ОС - она ​​возвращается диспетчеру кучи процесса. Из соображений эффективности он не обнуляется.

Когда процесс выделяет виртуальную память, большинство ОС передает ему страницу с обнулением. Это предотвращает «утечку» памяти из одного процесса в другой и вызывает проблемы безопасности, как вы упомянули.

Если у вас есть данные в вашем процессе, которые вы не хотите хранить в памяти (например, пароль пользователя) , вы несете ответственность за его обнуление. Windows предоставляет для этого SecureZeroMemory API.

6
ответ дан 18 December 2019 в 05:11
поделиться

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

#define FREE(P) ((void)(free((P)), (P) = NULL))

Конечно, если выражение, переданное в FREE , имеет побочные эффекты, значит, вы только что открыли большую банку червей ...

6
ответ дан 18 December 2019 в 05:11
поделиться

Также есть bzero (3).

0
ответ дан 18 December 2019 в 05:11
поделиться

Изначально C был разработан как язык реализации системы, поэтому операции на C, как правило, выполняются так же быстро и практически до предела. практично. Одним из ключевых моментов философии проектирования является то, что вы можете взять несколько быстрых операций и превратить их в одну более медленную и безопасную операцию, но вы не можете взять более медленные и безопасные операции и сделать более быструю.

Если вам нужна функция без нуля, вы можете написать ее и использовать ее вместо free () . Если вас беспокоит безопасность, я бы порекомендовал это.

3
ответ дан 18 December 2019 в 05:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: