Re: realloc(): invalid next size
- From: "Rod Pemberton" <do_not_have@xxxxxxxxxxxxxxxxx>
- Date: Wed, 12 Apr 2006 14:13:43 -0400
"Pedro Graca" <hexkid@xxxxxxxxxxx> wrote in message
news:slrne3q03s.c3j.hexkid@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Rod Pemberton wrote:'magic
"Chris Torek" <nospam@xxxxxxxxx> wrote in message
news:e1gq3i0930@xxxxxxxxxxxxxxxxxxxx
(Seriously: C89 specifically said that realloc(NULL,n) was equivalent
to malloc(n), and malloc(0) *could* be equivalent to malloc(1); it
then also said that realloc(p,0) was equivalent to free(p); so what
then is realloc(NULL,0) -- is it like malloc(0) and hence like
malloc(1), or is it just free(NULL)?)
If your question wasn't rhetorical, this realloc probably answers your
question. It has undefined behavior since it doesn't determine the
mystery size' of s1...
void *my_realloc (void *s1, size_t size)
{
void *s2=NULL;
if (size!=0||s1==NULL)
s2 = malloc(size);
else
free(s1);
if (s1!=NULL)
memcpy(s2, s1, size);
return(s2);
}
Hmm, there seems to be something wrong with this my_realloc():
new_pointer = my_realloc(NULL, 100); /* ok */
new_pointer = my_realloc(NULL, 0); /* ok */
new_pointer = my_realloc(old_pointer, 100); /* old_pointer not free'd */
That's a simple fix:
if (s1!=NULL)
{
memcpy(s2, s1, size);
free(s1);
}
new_pointer = my_realloc(old_pointer, 0); /* memcpy(NULL, ????, 0); */
You've got that wrong. The last case is memcpy(new_pointer,old_pointer,0);
i.e., new_pointer = my_realloc(old_pointer, 0); /*
memcpy(new_pointer,old_pointer,0); */
If size is zero, s1 is freed (which doesn't set s1 to NULL) and s2 is
returned which is NULL.
In the last example, will the call to memcpy() invoke UB? Or, because
size is 0 (zero), it doesn't matter what the pointers point to?
As I said, you've got the last one wrong. No NULL is ever passed to
memcpy(), but a size zero is. To eliminate the size zero problem, you need
to know the old size, and check that it isn't zero. Which as Chris Torek's
example shows, it's based on compiler secrets.
The point of my reply was that Chris Torek's solution will pass NULL's for
'old' that _could_ "invoke" (I really don't like "invoke," it implies a
guaranted action...) UB for the first two situations:
new_pointer = my_realloc(NULL, 100); /* not Ok for ChrisT example*/
new_pointer = my_realloc(NULL, 0); /* not Ok for ChrisT example*/
(If you're keeping score, Chris has two UB, one size zero problem. And,
mine had one coding error, and one size zero problem.)
A closer corrected realloc, would be some merger of mine and Chris', with
zero correction for size:
void *realloc (void *s1, size_t size)
{
void *s2=NULL;
size_t oldsize = __some_sort_of_magic_done_here(old);
if (size!=0||s1==NULL)
s2 = malloc(size);
else
free(s1);
if (s1!=NULL)
{
size=oldsize<size?oldsize:newsize;
if(size==0)
size=1;
memcpy(s2, s1, size);
free(s1);
}
return(s2);
}
HTH,
Rod Pemberton
.
- Follow-Ups:
- Re: realloc(): invalid next size
- From: Pedro Graca
- Re: realloc(): invalid next size
- From: Rod Pemberton
- Re: realloc(): invalid next size
- References:
- realloc(): invalid next size
- From: Deephay
- Re: realloc(): invalid next size
- From: Michael Wojcik
- Re: realloc(): invalid next size
- From: Pedro Graca
- Re: realloc(): invalid next size
- From: Chris Torek
- Re: realloc(): invalid next size
- From: Rod Pemberton
- Re: realloc(): invalid next size
- From: Pedro Graca
- realloc(): invalid next size
- Prev by Date: Re: how to create sub-directory if it doesn't exists?
- Next by Date: Re: LISP generalized lists in C
- Previous by thread: Re: realloc(): invalid next size
- Next by thread: Re: realloc(): invalid next size
- Index(es):
Relevant Pages
|