Повреждение кучи в C

int main ()
{
    int * b;
    b = (int*) malloc (1);
    *b=110000;
    free (b);
    return 0;
}

Почему повреждение кучи происходит в free (b);?

ИМО, повреждение кучи уже происходит в *b=110000;.


person Alan    schedule 13.10.2010    source источник
comment
К вашему сведению, вам не нужно использовать malloc.   -  person Nyan    schedule 13.10.2010
comment
Вы связались с Вальгринд? Это скажет вам, где происходит недопустимая запись, это должна быть строка 5 в приведенном выше примере.   -  person Christoffer    schedule 13.10.2010


Ответы (5)


Аргумент malloc() — это количество байтов, которое нужно выделить. Вам нужно использовать:

b = (int*) malloc(sizeof(int));

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

person Ned Batchelder    schedule 13.10.2010
comment
Мой вопрос: почему *b=110000; не повреждается, поскольку использует больше места, чем доступно? - person Alan; 13.10.2010
comment
Это присваивание портит кучу, это свободный вызов обнаруживает повреждение. - person Ned Batchelder; 13.10.2010
comment
@Alan - это портит вашу кучу. Только то, что вы можете или не можете увидеть последствия немедленно. - person Manoj R; 13.10.2010
comment
-1, Это хороший совет, как сделать правильную программу, но он не отвечает на вопрос. - person Edmund; 13.10.2010
comment
@Edmund Комментарий @Ned Batchelder на самом деле является ответом, я приму его, когда позволит время. - person Alan; 13.10.2010
comment
Ответ @Alan должен быть: это потому, что ... . Сделайте это, чтобы исправить ... . - person Andrey; 13.10.2010
comment
@ Эдмунд и @ Андрей, нет смысла говорить, это не отвечает на вопрос. Если вы знаете лучший ответ, добавьте его сюда. Если вы не знаете ответа, но считаете, что мой ответ не дает всего, что вам нужно, задайте дополнительный вопрос. - person Ned Batchelder; 13.10.2010

Это *b=110000; Потому что вы выделяете память для одного байта, а затем назначаете ей int, который больше одного байта. Либо у вас может быть b= (int *)malloc(sizeof(int)) или вместо int *b вы можете иметь char *b, а затем привести указатель malloc к char *. Код может даже работать, если вы присвоите значение меньше 128 (из-за знакового символа) для *b.

РЕДАКТИРОВАТЬ: - Я думаю, что иногда даже это будет работать без каких-либо хлопот. Потому что компилятор может выделить более одного байта памяти для быстрого доступа к данным.

person Manoj R    schedule 13.10.2010

Повреждение кучи действительно происходит уже при назначении *b=11000, но оно не обнаруживается до вызова free(b), потому что это первая точка, в которой целостность кучи снова проверяется.

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

person Bart van Ingen Schenau    schedule 13.10.2010

Код записывает в блок памяти больше данных, чем доступно для него, что искажает начало следующего действительного блока памяти.

Использование char * вместо int * и запись значения от -128 до 127 в *b должно исправить это.

person VHampiholi    schedule 13.10.2010

Ваше значение 110000 --> 0x01ADB0 --> 3 bytes. Вы записываете 3 байта данных в 1 байт, который вы запросили из кучи.

Важно знать, что malloc делает с параметром 1 и что вы помещаете в эту память.

malloc() выделяет размер байтов и возвращает указатель на выделенную память. Также не забудьте проверить указатель перед его использованием и инициализацией локальных переменных.

person alejandro oyarbide    schedule 12.02.2021