This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: malloc attributes and realloc


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;
    }
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]