-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Knight wrote:
> Hi,
> I used to get a SegFault in the following code:
>
> char *x, *y;
> x = malloc(somesize);
> y = realloc(x, someothersize);
> free(x);
>
> I CANNOT believe that (Linux) man pages for malloc/realloc don't
> mention that you cannot call free() in this situation. Is this a
> "feature" or a "bug" in my Linux (glibc) distro?
It is neither. It is a flaw in your code, and in your understanding of what
realloc() does.
To quote the realloc(3) manpage...
realloc() changes the size of the memory block pointed to by ptr to
size bytes. The contents will be unchanged to the minimum of the old
and new sizes; newly allocated memory will be uninitialized. If ptr is
NULL, the call is equivalent to malloc(size); if size is equal to zero,
the call is equivalent to free(ptr). Unless ptr is NULL, it must have
been returned by an earlier call to malloc(), calloc() or realloc().
If the area pointed to was moved, a free(ptr) is done.
Please note that last line, and re-examine your code.
> x = malloc(somesize);
Assuming malloc() succeeded, x now points at a block of allocated memory
> y = realloc(x, someothersize);
Assuming that realloc() succeeded, and had to change pointers ("area pointed
to was moved"), the area pointed to by x is now free()ed by realloc(), and the
data is located at the /new/ location, pointed to by y
> free(x);
Now, you free() an area of memory already free()ed by realloc(). Naughty,
naughty; you violated the rules of the language and of the standard library
and free()ed an invalid pointer. Chaos ensues, as it may when you break the
rules. (If you don't believe me, read the manpage for free(3)...
free() frees the memory space pointed to by ptr, which must have been
returned by a previous call to malloc(), calloc() or realloc(). Other-
wise, or if free(ptr) has already been called before, undefined behav-
iour occurs. If ptr is NULL, no operation is performed.
and note that "if free(ptr) has already been called before, undefined
behaviour occurs". They aren't kidding.
What you /should/ have coded is
x = malloc(somesize);
x = realloc(x, someothersize);
/* don't free(x) */
See the difference?
- --
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
- ---------- Slackware - Because I know what I'm doing. ------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Armoured with GnuPG
iD8DBQFHtObYagVFX4UWr64RAly0AJ4xVkvHJqiE7UgGKx6wSw 1lwfVvTwCgggGF
EWeFsO6x3tB/cdKoNIdXJjA=
=4I8B
-----END PGP SIGNATURE-----