Free вызывает ошибку: free (): неверный указатель: 0x0000000001d04018 - PullRequest
0 голосов
/ 30 апреля 2018

Я попытался скомпилировать следующий код:

#include <stdio.h>

void main()
{
    int *p = (int*) malloc(4*sizeof(int));
    p++;
    p++;
    free(p);
}

Но это дает мне следующую ошибку.

* Ошибка в `/home/a.out ': свободна (): неверный указатель: 0x0000000001d04018 *
Отменено.

Я думаю, что я все еще в выделенных пределах размера 4 дюйма. Но тогда почему неверный указатель. Может ли кто-нибудь помочь.

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

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

Если вы измените указатель, у вас будут подобные ошибки, этот измененный указатель никогда не будет выделен.

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

0 голосов
/ 30 апреля 2018

Вы вызываете неопределенное поведение.

С бесплатное руководство :

Функция free () освобождает пространство памяти, на которое указывает ptr, , которое должно быть возвращено предыдущим вызовом malloc (), calloc () или realloc () . В противном случае или, если free (ptr) уже был вызван ранее, происходит неопределенное поведение.

Неважно, находитесь ли вы в выделенном регионе или нет. Указатель должен быть таким же, который был выделен ранее.

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

0 голосов
/ 30 апреля 2018

Контракт на malloc и free довольно прост. Значение указателя (адрес), который вы передаете free, должно быть точно значение указателя, полученное из malloc.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...