C вопросом о свободе () - PullRequest
       6

C вопросом о свободе ()

2 голосов
/ 08 декабря 2010
#include <stdio.h>
int main ()

{

   int *p = (int *)malloc((100*sizeof(int)));

   p++;

   free(p);

/* do something */

return 0;

}

Вопросы:

  1. Будет ли свободна память, начиная с местоположения p + 1 (скажем, если malloc вернул 0x1000, освобождаемая память будет с 0x1004, предполагая 4целое число байтов)?

  2. Существуют ли какие-либо ошибки в этом коде, кроме того факта, что 4 байта из 0x1000 (если malloc вернул 0x1000) не могут использоваться (если вы не сделаете p-- ииспользуйте адрес)

Ответы [ 5 ]

12 голосов
/ 08 декабря 2010

Это неопределенное поведение - вы должны передать в free() точно такой же указатель, какой вы получили из malloc().С вашим кодом может случиться что угодно - вероятно, куча будет повреждена.

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

1 голос
/ 08 декабря 2010

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

0 голосов
/ 08 декабря 2010

в стандарте это поведение "неопределено", но на самом деле, ничто не будет освобождено.причина в том, что в malloc хранится список выделенных чанков, каждый чанк идентифицируется своим начальным адресом.p + 1 отсутствует в этом списке, поэтому free найдет кусок для освобождения и ничего не сделает.

0 голосов
/ 08 декабря 2010

Эй, я пробовал этот код через gcc, и он остановился на:

*** glibc detected *** ./a.out: free(): invalid pointer: 0x0829600c ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x7be591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x7bfde8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x7c2ecd]

Так что, согласно вашему первому ответу, вы не можете освободить следующую ячейку памяти.и для второго вопроса: и четыре байта не будут использоваться, если вы не сделаете p - и этот код будет работать нормально, если вы не измените содержимое следующей области памяти и не сможете использовать выделенную область памяти, выполнив p -

0 голосов
/ 08 декабря 2010

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

...