Simple realloc() question

S

Sensei

I'm sorry to always bother you guys on simple C topics... but here
again I go :)

What does the standard C99 (and if you have knowledge, pre-C99 also)
say about the behavior of realloc() on different new sizes?

AFAIR, realloc with a bigger size must return the new address, or NULL
if it fails. I was wondering, what happens when you ask realloc to
shrink the allocated space? Will it free the remaining memory or not?

Thanks to anyone!
 
G

Guest

Sensei said:
I'm sorry to always bother you guys on simple C topics... but here
again I go :)

What does the standard C99 (and if you have knowledge, pre-C99 also)
say about the behavior of realloc() on different new sizes?

AFAIR, realloc with a bigger size must return the new address, or NULL
if it fails.
Correct.

I was wondering, what happens when you ask realloc to
shrink the allocated space? Will it free the remaining memory or not?

As far as the standard is concerned, realloc is allowed to return a
null pointer even when asking for less memory than you already have.
It is also allowed to return a non-null pointer that points to more
memory than the amount you asked for.
 
F

Flash Gordon

Sensei wrote, On 07/02/07 08:51:
I'm sorry to always bother you guys on simple C topics... but here again
I go :)

What does the standard C99 (and if you have knowledge, pre-C99 also) say
about the behavior of realloc() on different new sizes?

AFAIR, realloc with a bigger size must return the new address, or NULL
if it fails.

Note that the new address *might* be the same as the old address.
> I was wondering, what happens when you ask realloc to
shrink the allocated space? Will it free the remaining memory or not?

It might move on shrinking as well. Whatever happens if the realloc
succeeds (it could fail on shrinking) you can no longer access the
memory you have said you no longer want.
 
A

Andrey Tarasevich

Sensei said:
I'm sorry to always bother you guys on simple C topics... but here
again I go :)

What does the standard C99 (and if you have knowledge, pre-C99 also)
say about the behavior of realloc() on different new sizes?

Nothing that specific.
AFAIR, realloc with a bigger size must return the new address, or NULL
if it fails.

If by "new" you mean "different from the old", then this is not the case.
'realloc' with a bigger size might quite possibly return the same address.
I was wondering, what happens when you ask realloc to
shrink the allocated space? Will it free the remaining memory or not?

If by "free" you me "make available to further allocation requests", then the
answer is "it normally should". But there are many things there that can be done
differently.
 
C

christian.bau

Sensei wrote, On 07/02/07 08:51:




Note that the new address *might* be the same as the old address.

Not really. The old pointer value is indeterminate if realloc returns
a non-null pointer, so comparing old and new pointer would invoke
undefined behavior.
 
R

Richard Tobin

Note that the new address *might* be the same as the old address.
[/QUOTE]
Not really. The old pointer value is indeterminate if realloc returns
a non-null pointer, so comparing old and new pointer would invoke
undefined behavior.

If you really want to, you can test whether the address has changed by
copying the old pointer to a suitably-sized byte array before calling
realloc(), and doing the same with the new one. I suppose this could
give false positives if the pointer has padding bits and realloc()
sets them differently.

-- Richard
 
C

CBFalconer

.... snip stuff that had no corresponding attribution lines ...
If you really want to, you can test whether the address has
changed by copying the old pointer to a suitably-sized byte array
before calling realloc(), and doing the same with the new one. I
suppose this could give false positives if the pointer has
padding bits and realloc() sets them differently.

<academic interest only>
You can beat that by using the %p specifier in a sprintf call.

char inputvalue[ENOUGH];
char outputvalue[ENOUGH];

void *p, *tmp;

p = malloc(SOMETHING];
sprintf(inputvalue, "%p", p);
if (tmp = realloc(p, SOMETHINGELSE)) p = tmp;
else {
puts("No memory"); exit(EXIT_FAILURE);
}
sprintf(outputvalue, "%p, p);
if (strcmp(inputvalue, outputvalue)) puts("pointer changed");
else puts("pointer unchanged after size change");

with suitable #includes and #defines, should be portable.
</academic interest only>

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
M

matevzb

Not really. The old pointer value is indeterminate if realloc returns
a non-null pointer, so comparing old and new pointer would invoke
undefined behavior.
Yes really. He didn't mention any comparisons, he just stated that the
pointer can have the same value. N1124 says (7.20.3.4): "The realloc
function returns a pointer to the new object (which may have the same
value as a pointer to the old object), or a null pointer if the new
object could not be allocated."
 
F

Flash Gordon

CBFalconer wrote, On 08/02/07 00:13:
... snip stuff that had no corresponding attribution lines ...
If you really want to, you can test whether the address has
changed by copying the old pointer to a suitably-sized byte array
before calling realloc(), and doing the same with the new one. I
suppose this could give false positives if the pointer has
padding bits and realloc() sets them differently.

<academic interest only>
You can beat that by using the %p specifier in a sprintf call.

char inputvalue[ENOUGH];
char outputvalue[ENOUGH];

void *p, *tmp;

p = malloc(SOMETHING];
sprintf(inputvalue, "%p", p);
if (tmp = realloc(p, SOMETHINGELSE)) p = tmp;
else {
puts("No memory"); exit(EXIT_FAILURE);
}
sprintf(outputvalue, "%p, p);
if (strcmp(inputvalue, outputvalue)) puts("pointer changed");
else puts("pointer unchanged after size change");

with suitable #includes and #defines, should be portable.
</academic interest only>

There is a guarantee that having printed it with %p you c
an get it back with scanf, however I am not aware of any guarantee that
each time you print the same pointer value you will get the same
representation. After all, if it just prints the bytes in hex then if
there are multiple ways of producing the same pointer value the printed
versions would be different.
 
K

Kenneth Brody

christian.bau said:
Not really. The old pointer value is indeterminate if realloc returns
a non-null pointer, so comparing old and new pointer would invoke
undefined behavior.

Just because you technically can't compare the old and new pointers
doesn't mean that they aren't the same. Besides, he said nothing
about comparing the old and new. He merely mentioned that the new
address might be the same as the old one.


What about this untested code?

==========

#include <stdlib.h>

/* Assumption:
* The output of "%p" formatting must fit in 127 bytes.
*/
int realloc_test(char *oldpt, size_t newsize, char **newpt)
{
char oldbuf[128], newbuf[128];

sprintf(oldbuf,"%p",(void *)oldpt);

*newpt = realloc(oldpt,newsize);
sprintf(newbuf,"%p",(void *)*newpt);

#if DEBUG
printf("%s\n%s\n",oldbuf,newbuf);
#endif
if ( strcmp(oldbuf,newbut) == 0 )
{
return 1;
}
else
{
return 0;
}
}

==========

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
W

Walter Roberson

Flash Gordon said:
There is a guarantee that having printed it with %p you c
an get it back with scanf, however I am not aware of any guarantee that
each time you print the same pointer value you will get the same
representation.

Correct -- the scanned pointer only has to compare equal, not
necessarily be the same internal representation.
 
G

Guest

Kenneth said:
christian.bau said:
Not really. The old pointer value is indeterminate if realloc returns
a non-null pointer, so comparing old and new pointer would invoke
undefined behavior.

Just because you technically can't compare the old and new pointers
doesn't mean that they aren't the same. Besides, he said nothing
about comparing the old and new. He merely mentioned that the new
address might be the same as the old one.


What about this untested code?
[...]
sprintf(oldbuf,"%p",(void *)oldpt);

*newpt = realloc(oldpt,newsize);
sprintf(newbuf,"%p",(void *)*newpt);
[...]

I think it is allowed to give you two identical strings even if the
pointers are really different. You can use memcpy() and memcmp() in a
similar way to avoid that problem; that may tell you the pointers are
different when they really are the same, but if it tells you they are
the same, you can be pretty sure they are.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top