|
||||||||
|
|
#1
|
|
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? Knight |
|
#2
|
|||
|
|||
|
-----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----- |
|
#3
|
|||
|
|||
|
On Feb 14, 5:01 pm, Knight <knightt...@yahoo.com> 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? Your code is nonsensical. It's as pointless as: char *x, *y; x=malloc(somesize); y=x; free(y); free(x); Surely you wouldn't be surprised that the second 'free' would cause a problem. It's the same in your code. You "consume" 'x' twice, once be exchanging it for 'y' and then a second time by freeing it. DS |
|
#4
|
|||
|
|||
|
Knight <(E-Mail Removed)> writes:
> 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? The man page on my debian testing system says: 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- ior occurs. If ptr is NULL, no operation is performed. 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. So if (x != y), y is freed. Looking at your code, I don't see anyplace where you checked to make sure (x != y) -- since realloc() doesn't guarantee that, your code is broken even if it didn't implicitly call free() when the block does get moved. |
|
#5
|
|||
|
|||
|
Lew Pitcher <(E-Mail Removed)> writes:
<snipping a lot of good stuff> > What you /should/ have coded is > > x = malloc(somesize); > x = realloc(x, someothersize); > /* don't free(x) */ > > See the difference? Note that Lew's code is also simpler, since you don't have to deal with a new variable name for your pointer. |
|
#6
|
|||
|
|||
|
OK I deserve the tomatoes. Can I just say, I also have the same man
page (realloc() changes the size ... If the area pointed to was moved, a free(ptr) is done.) I completely missed the point of the last sentence. Q about Lew's code: x = malloc(100); x = realloc(x, 200); if realloc fails, x will become NULL and that will leave a 100-byte hole in the memory, will it not? |
|
#7
|
|||
|
|||
|
Knight <(E-Mail Removed)> writes:
> OK I deserve the tomatoes. Can I just say, I also have the same man > page (realloc() changes the size ... If the area pointed to was > moved, a free(ptr) is done.) I completely missed the point of the last > sentence. > Q about Lew's code: > x = malloc(100); x = realloc(x, 200); > if realloc fails, x will become NULL and that will leave a 100-byte > hole in the memory, will it not? Hmmmm... as I read the man page, you appear to be correct. |
|
#8
|
|||
|
|||
|
Joe Pfeiffer wrote:
> Knight <(E-Mail Removed)> writes: > >> OK I deserve the tomatoes. Can I just say, I also have the same man >> page (realloc() changes the size ... If the area pointed to was >> moved, a free(ptr) is done.) I completely missed the point of the last >> sentence. >> Q about Lew's code: >> x = malloc(100); x = realloc(x, 200); >> if realloc fails, x will become NULL and that will leave a 100-byte >> hole in the memory, will it not? > > Hmmmm... as I read the man page, you appear to be correct. Historically (pre-ansi?) realloc failure resulted in the block being freed. It was kind of toss your data to the wind and hope you get it back. |
|
#9
|
|||
|
|||
|
On Feb 18, 10:49 am, Joe Beanfish <j...@nospam.duh> wrote:
> Historically (pre-ansi?) realloc failure resulted in the block > being freed. It was kind of toss your data to the wind and hope > you get it back. That's kind of odd, because it's actually harder to write a 'realloc' that fails that way. DS |
![]() |
| Tags |
| free, realloc |
| Thread Tools | |
| Display Modes | |
|
|