Как я могу узнать, что выделенное пространство успешно освобождено?

#c #memory

#c #память

Вопрос:

Кто-нибудь знает, как мы можем проверить, успешно ли освобождено выделенное пространство? На странице руководства написано, что «free () не возвращает значения».

Ответ №1:

Возможны три случая:

 free( NULL );     // does nothing, so always works
free( malloc(42) );  // does something, always works
free( 666 );      // undefined behaviour - returned value would be meaningless
  

Таким образом, нет случая, когда тестирование free() имело бы смысл.

Комментарии:

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

2. @alwin Ну, программа может и не аварийно завершать работу — в этом чудо неопределенного поведения — но в принципе, да.

3. Если ваша программа верна, free всегда работает. Единственный раз, когда это может привести к «чему-то еще» (например, сбою), это если вы вызвали UB. Правильная программа никогда не делает ничего, что могло бы вызвать UB.

4. @R .. Извините, что здесь означает UB?

5. @alwinlin UB == неопределенное поведение

Ответ №2:

Возвращаемое значение отсутствует, потому что нет случая сбоя. free всегда успешно. Проверять нечего.

Обратите внимание, что это предполагает, что вы используете его правильно. Если вы передаете free указатель, который недопустим в качестве аргумента free , например, неинициализированный указатель, указатель на уже освобожденный объект или указатель на объект, не полученный malloc , то ваша программа имеет неопределенное поведение. Это не ошибка, о которой следует сообщать; скорее это означает, что могло случиться что угодно.

Ответ №3:

«Неправильное» свободное пространство приведет к сбою вашего приложения, поэтому нет необходимости проверять, работает ли оно 🙂

Пример:

 #include <stdlib.h>

int main(int argc, char **argv) {
    char *a = malloc(sizeof(*a) * 10);
    free(a);
    free(a);
    return 0;
}
  

$ ./example
* обнаружен glibc ./пример: двойное освобождение или повреждение (fasttop): 0x08a3e008 **
======= Обратная трассировка: ========= / lib/ libc.so.6( 0x6c501)[0x17c501]

Комментарии:

1. Это если вам действительно повезет. Менее удачным результатом было бы то, что ваша программа выполнит произвольный код из файла, который она использует в качестве входных данных .. 🙂

Ответ №4:

Если вы хотите проверить внутреннюю работу распределителя кучи, я не думаю о стандартном способе сделать это.

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

Комментарии:

1. Было бы бессмысленно free обнулять память, потому что после free считывать байты из этой памяти незаконно.

2. free может сделать это, если он сделает это перед освобождением памяти.

3. Эли: Я думаю, смысл был в том, что, поскольку после free() все равно ничто не может получить доступ к памяти, зачем писать туда материал, который никогда не сможет быть прочитан снова?

4. Это верно, если процессор и ОС предоставляют вам такую возможность. Во многих (в основном встроенных) системах это не всегда верно, и вы можете получить доступ (по крайней мере, прочитать) к данным из кучи, даже если они уже были освобождены.