On Sun, 12 Sep 2004 09:27:50 GMT
On 17 Aug 2004 02:29:09 -0700, "ravi" <
[email protected]>
wrote:
I have a situation where i want to free the memory pointed by a
pointer, only if it is not freed already. Is there a way to know
whether the memory is freed or not?
in the borland c 5.3 compiler *seems*
p=malloc(size);
<code_sinp>
if(p==0 || ( ((unsigned*)p)[-1]&0x1 ) ) printf("not allocated")
else printf("allocated");
For all you know this might only work on Sundays. It is undefined
behaviour and as has been discussed here there is NO standard way to
determine if the object a pointer points to has been freed or not.
In fact, even with your specific implementation I am willing to bet
that there are situations where (unsigned*)p)[-1] would actually
point in to another object.
it is easy to speak (but if p!=0 seems I have right). Find an exaple
where it doesn't work
If you send me your computer system I'll do that. However, my machine is
different so it behaves differently when undefined behaviour is invoked.
The standard says that what you are doing is undefined therefor
literally anything can happen.
Anyone recommending doing the sort of thing you are suggesting is either
very ignorant about C or very idiotic. However, just to give you one
example that could cause your test to fail (although it might not since
undefined behaviour is undefined and therefor anything can happen):
{
unsigned *q = malloc(sizeof *q);
unsigned *p = malloc(sizeof *p);
free(p);
free(q);
q = malloc(2 * sizeof *p);
q[0]=1;
q[1]=1;
U=unsigned
if you want to rewrite ((U)p)[-1] in the way it seems freed
there is one chance if here you write
q[2] = 2; but it is out of bounds
if 41:4 means a space of 4 chars (here unsigned) that has value 41
decimal
it seems malloc return some vector of a list like this
|41:4|vector:40|68:4|vector:68|10051:4|vector:1000|space:50|4:4|vector:4|
^ not in use ^use ^ not in use
}
One way in which this could cause your test to fail is if the second
time space is malloced for q it uses the space immediately before where
p was allocated as part of its allocation. This would be a perfectly
reasonable thing for the malloc implementation to do.
NEVER rely on looking outside the memory that your implementation tells
you is yours.
Ok agree but your exaple doesn't fit
Borland c - compiler 5.6 seems agree with boralnd c compiler 5.3 in
the 'good' result
#include <stdio.h>
#include <stdlib.h>
/* 1 means not free; 0 means free */
int controlla(void* p)
{if(p==0 || ( ((unsigned*)p)[-1] & 0x1 ) )
return 0;
return 1;
}
int main(void)
{int j;
unsigned i, *u, *v;
char *p;
/*-----------------------*/
u=malloc( sizeof *u);
v=malloc( sizeof *v);
v[0]=0xDEFAB123; u[0]=0xBCBCE123;
free(u); free(v);
u=malloc(2* sizeof *u);
u[1]=0xAEAEFBF2; /* note 2 in u[1] */
if(controlla(v)==1)
{printf("NON FUNZIONA \n");}
//printf("v=%p; u=%p :%x:%x:%x:%x:%x:%x:%x:%x:%x\n", (void*)v ,
(void*)u ,
// u[-1], *u, u[1], u[2], u[3], u[4], u[5], u[6], *v
);
free(u);
for( i=0; i<50000; ++i)
{p=malloc(i);
if(i!=0)
p[i-1]=2;
if(p!=0 && controlla(p)==0)
{printf("p=%p prima cont=%u\n", (void*)p, i);
if(p!=0) printf(" p[-1]=%u\n", ((unsigned*)p)[-1] );
exit(0);
}
free(p);
if(controlla(p)==1)
{printf("p=%p dopo cont=%u\n", (void*)p, i);
if(p!=0) printf(" p[-1]=%u\n", ((unsigned*)p)[-1] );
exit(0);
}
}
printf("Alla fine count=%u", i);
return 0;
}