Re: realloc(): invalid next size



Rod Pemberton wrote:
"Pedro Graca" <hexkid@xxxxxxxxxxx> wrote in message
news:slrne3q03s.c3j.hexkid@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Rod Pemberton wrote:
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);
free(s1);
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:
[fix incorporated in the code above, check '>' marks]

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.

Right. Let's run "my_realloc(valid_old_pointer, 0);" step by step ...

void *my_realloc (void *s1, size_t size)
{
void *s2=NULL;
/* s1 --> valid_old_pointer
* s2 --> NULL
* size --> 0 */

if (size!=0||s1==NULL)
s2 = malloc(size);
else
free(s1);
/* s1 --> free'd valid_old_pointer
* s2 --> NULL
* size --> 0 */

if (s1!=NULL)
memcpy(s2, s1, size);
/* And here we go ...
* s2 is NULL, s1 is the free'd valid_old_pointer, size is 0
* so
*
* ...
*
* memcpy(NULL, ????, 0); */

return(s2);
}

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.

Where did I go wrong in my step-by-step run of my_realloc()?

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.

Yes, I understand this is nothing more than an exercise in second
guessing the compiler secrets ... but I feel it's a good exercise to aid
in developing my knowledge of C.

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
.



Relevant Pages

  • Re: Marshaling Value Types
    ... First, the void* params are concerning if they are pointers to actual data, ... > UINT32 Minor; ... The C# code give me a return value of zero for the> BioAPI_Init call, and both version.major and version.minor are zero. ... >>> I've read that, with the compact framework, MarshalAs is not available> and ...
    (microsoft.public.pocketpc.developer)
  • Re: void vs void* (philosophical question)
    ... ordinary object type whose size is zero, ... its value, upon conversion to any other scalar type, would be ... void retval; ... I think your not-quite-C language is consistent, ...
    (comp.lang.c)
  • Re: ACBL Bulletin "Bidding Box" scoring?
    ... Are you going to give them zero for not playing SA? ... What do you bid? ... Did you mean to give us an example hand with a spade void instead of a ...
    (rec.games.bridge)
  • Re: Obvious bug in /sys/i386/include/bus.h (was: bus_at386.h)
    ... >> Adding that extra check for zero transfer length is not going to affect ... static __inline void ...
    (freebsd-hackers)
  • Re: void vs void* (philosophical question)
    ... ordinary object type whose size is zero, ... its value, upon conversion to any other scalar type, would be ... void retval; ... Reading email is like searching for food in the garbage, ...
    (comp.lang.c)