How to know the memory pointed by a ptr is freed?

F

Flash Gordon

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.
 
R

Randy Howard

wrong: it is an error, if debug mode it has to be reported

What are you going on about? THERE IS NO "debug mode" in standard C.
Hint: Platform and/or compiler implementation specifics are not
authoritative here.
 
A

ala

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
 
A

ala

Thats not /entirely/ true. Consider the NDEBUG macro.


Agreed.

if you are god and don't make errors in "bounds out" I'm agree but I
make errors and have the need of a routine that controll (in debug
mode) if some bound in some array ( seems to be (unsigned*)p [-1] and
(unsigned*)p [sizeof(p)/sizeof(unsigned) +
sizeof(p) % sizeof(unsigned)] ) is not proper re-written
 
P

pete

ala said:
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

It doesn't ever work. It doesn't answer the question.
(p == 0) wouldn't tell you if p has been freed
even if it weren't undefined behavior.
 
F

Flash Gordon

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

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.
 
A

ala

if you are god and don't make errors in "bounds out" I'm agree but I
make errors and have the need of a routine that controll (in debug
mode) if some bound in some array ( seems to be (unsigned*)p [-1] and
(unsigned*)p [sizeof(p)/sizeof(unsigned) +
sizeof(p) % sizeof(unsigned)] ) is not proper re-written
I mean
(unsigned*)p [sizeof(p)/sizeof(unsigned) +
( (sizeof(p) % sizeof(unsigned)) ? 1: 0) ] )
 
A

ala

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

ala

On Sun, 12 Sep 2004 11:12:10 +0100, Flash Gordon

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

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

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 :)
ok you are right this seems show it
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define U unsigned

/* 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)
{unsigned i, *u, *v, j[5], k, x;
char *p[5];
/*-----------------------*/
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);
srand((U)time(0));

for( i=0; i<5000; ++i)
{for(k=0; k<5; ++k)
j[k]=rand()%5000;
for(k=0; k<5; ++k)
p[k]=malloc(j[k]);
for(x=0; x<5 ; ++x)
if(p[x]==0 && j[x]!=0)
{label:
for( x=0; x<5; ++x)
free(p[x]);
exit(0);
}
else for(k=0; k<j[x] ; ++k)
p[x][k]=2;
for(x=0; x<5; ++x)
if(p[x]!=0 && controlla(p[x])==0)
{printf("p=%p prima cont=%u\n", (void*)p[x], i);
if(p!=0)
printf(" p[-1]=%u\n", ((unsigned*)(p[x]))[-1]);
goto label;
}
for( x=0; x<5; ++x)
free(p[x]);
for( x=0; x<5; ++x)
if(controlla(p[x])==1)
{printf("p=%p dopo cont=%u x=%u\n", (void*)p[x], i, x);
if(p!=0)
printf(" p[-1]=%u\n", ( (unsigned*) (p[x]) )[-1] );
exit(0);
}
}
printf("Alla fine count=%u", i);
return 0;
}


C:>malloc
p=0084330C dopo cont=0 x=1
p[-1]=1758

C:>malloc
p=0084315C dopo cont=0 x=1
p[-1]=694

C:>malloc
p=0084315C dopo cont=0 x=1
p[-1]=694
 
R

RCollins

ala said:
Ravi said:
Flash Gordon wrote:

[ snip ]

I never know where (or whether) to enter these incredible threads
but I do have something to share on the Subject.

Some time ago I determined to add 'size_t size(void *);' to my
otherwise meager bag of tricks.

In the simplist case, a call to malloc() is directed to a wrapper
that actually calls malloc but 'remembers' the size_t argument as
well as the void* return and saves them in a simple linked list.

A call to size(void *p) trips through the linked list looking for
the vallue of p and returns the size of the allocation if found,
else 0. Perfect.

Of course, I wrap free(void *p) as well. We trip through the list
looking for p and freeing it if we find it and removing p's node

from the list. Of course, if we don't find p in the list, we do nothing.

That's when it struck me, I can pass anything to free() and if it's
not found in the list, nothing happens. No danger.


So, if you call free() the node is removed from the linklist then and
there ?

Exactly. The allocated memory is freed and then the node is removed
from the list and its memory is freed.

No danger. free(p) first looks up p in the list. If p is not in the
list, nothing is done.


wrong: it is an error, if debug mode it has to be reported

No ... from the C89 standard:

4.10.3.2 The free function


Synopsis

#include <stdlib.h>
void free(void *ptr);

Description

The free function causes the space pointed to by ptr to be
deallocated, that is, made available for further allocation. If ptr
is a null pointer, no action occurs. Otherwise, if the argument does
not match a pointer earlier returned by the calloc , malloc , or
realloc function, or if the space has been deallocated by a call to
free or realloc , the behavior is undefined.

Returns

The free function returns no value.
 
R

RCollins

RCollins said:
Ravi Uday wrote:



Flash Gordon wrote:

[ snip ]

I never know where (or whether) to enter these incredible threads
but I do have something to share on the Subject.

Some time ago I determined to add 'size_t size(void *);' to my
otherwise meager bag of tricks.

In the simplist case, a call to malloc() is directed to a wrapper
that actually calls malloc but 'remembers' the size_t argument as
well as the void* return and saves them in a simple linked list.

A call to size(void *p) trips through the linked list looking for
the vallue of p and returns the size of the allocation if found,
else 0. Perfect.

Of course, I wrap free(void *p) as well. We trip through the list
looking for p and freeing it if we find it and removing p's node


from the list. Of course, if we don't find p in the list, we do
nothing.


That's when it struck me, I can pass anything to free() and if it's
not found in the list, nothing happens. No danger.



So, if you call free() the node is removed from the linklist then and
there ?


Exactly. The allocated memory is freed and then the node is removed

from the list and its memory is freed.

Else, you might call free again on a freed pointer !! as in your
freeall()
call


No danger. free(p) first looks up p in the list. If p is not in the
list, nothing is done.



wrong: it is an error, if debug mode it has to be reported

No ... from the C89 standard:

4.10.3.2 The free function


Synopsis

#include <stdlib.h>
void free(void *ptr);

Description

The free function causes the space pointed to by ptr to be
deallocated, that is, made available for further allocation. If ptr
is a null pointer, no action occurs. Otherwise, if the argument does
not match a pointer earlier returned by the calloc , malloc , or
realloc function, or if the space has been deallocated by a call to
free or realloc , the behavior is undefined.

Returns

The free function returns no value.

Oops .. I mis-read the earlier posts. You are not talking about
NULL pointers, but on other (uninitialized or indeterminate) types
of pointers.

My earlier posting can be ignored.
 

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,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top