This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: malloc attributes and realloc
- From: Bruce Korb <bkorb at veritas dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 01 Jan 2004 19:53:51 -0800
- Subject: RE: malloc attributes and realloc
- Organization: Home
Sometimes these threads scare me. If the standard says stuff like,
``may have the same value as a pointer to the old'' then *SURELY*
there must be a way to make a determination as to whether or not
the pointer has the same value. As far as I know (a paultry 30
years with C), one makes that determination with: ``if (p == q)''
> #include <stdlib.h>
> int f(void) {
> int *p, *q;
> p = malloc(sizeof(int));
> *p = 0;
> q = realloc(p, sizeof(int));
> if (p == q) {
> *p = 1;
> return *q;
> }
> return 0;
> }
Even if what was addressed by 'p' is no longer valid, it is certainly
still valid to test to see if 'q' differs from 'p'.
> Does the alias machinery determine that p,q alias after all? Or is this
> illegal for some reason?
> [#2] The realloc function deallocates the old object pointed
> to by ptr and returns a pointer to a new object that has the
> size specified by size.
>
> I don't _think_ that you can validly make comparisons to a pointer
> after it has been freed. GCC probably could warn, and would be
> justified in warning, for the above case.
You can. You *cannot* compare the data pointed to by what now could
be unmapped memory, but by golly you certainly can compare the pointer
values.
> But after the free, p1 has an undefined value, and indeed the comparison
> p1==p2 is undefined at that point, so it is certainly not something the
> compiler has to worry about.
p1 has a _well_defined_value_. What is undefined is what might be at the
address pointed to by p1. It could be unmapped. ``p1 == p2'' is well
defined in its function, ``*p1 == *p2'' is undefined. It could fault.
> I cannot see how playing tricks with comparing bit patterns changes
> any of the above. Even if the program could portably detect the case
> where the same value was returned by realloc(), that would not change
> the fact that the old object doesn't exist any more and therefore
> cannot have aliases.
OK. The example needs to be slightly extended from the above
(please forgive some of the schlock, I did it for brevity).
Anyway, the following is a method of creating a table of undefined
length, reallocating as needed and adjusting the scanning pointer
only if the base address changes with the realloc:
typedef struct { int f1; int f2; } twoint_t;
int ct = 50;
twoint_t *p2i = malloc( ct * sizeof( twoint_t ));
twoint_t *p2 = p2i;
for (;;) {
char* p = fgets( buf, sizeof(buf), stdin );
if (p == NULL) break;
p2->f1 = strlen(p);
p2->f2 = atoi(p);
if (++p2 >= p2i + ct) {
twoint_t *px = realloc( p2i, (ct += 50) * sizeof(twoint_t));
if (px != p2i) {
p2 = px + (ct - 50);
p2i = px;
}
}