copy to pointer memory ?

M

MC

Hi
I have the following piece of code.

int *p;
p = malloc(10);
int *j;
j = p;
free(p);

Is this legal ? will j still point to the same
memory that p pointed to earlier ?
Can I access that memory using j ?

I read somewhere that even though free is
called, the memory is still available.
so in my case j should still point to that
memory right ?

MC
 
P

Pieter Droogendijk

int *p;
p = malloc(10);
int *j;
j = p;
free(p);

Is this legal ? will j still point to the same
memory that p pointed to earlier ?
Can I access that memory using j ?

Is it legal? No:

int *p;
p = malloc(10);
int *j;
Is illegal in C;

int *p;
int *j;
p = malloc (10);
Is legal.

Other than that, it's fine;
p is malloced, j = p so they both point to the same chunk, the chunk is freed
(note that free() frees the chunk p is pointing to, not p itself), so both j and
p are now pointing to unallocated space. Using them for anything besides
assigning them a new value may lead to undefined behaviour.
I read somewhere that even though free is
called, the memory is still available.

Sure it is. if you call malloc() again, chances are you get the same memory
again. I wouldn't design anything that counts on this though.
Seriously, once you free() a malloced chunk, dereferencing the pointer leads
to undefined behaviour. Just think of it as there being no way to get it back.
so in my case j should still point to that
memory right ?

No. j and p are pointing to the same address. The memory at that address was
freed. It's lost. Save yourself a lot of trouble in the future and accept it. If
you want to keep the memory, don't free it.
 
I

Irrwahn Grausewitz

Hi
I have the following piece of code.

int *p;
p = malloc(10);
int *j;
j = p;
free(p);

Is this legal ? Yes.

will j still point to the same
memory that p pointed to earlier ?
Yes, and p still points there, too.
Can I access that memory using j ?
No. You are not allowed to use it, since you have already
free()'d it.
I read somewhere that even though free is
called, the memory is still available.
This is not guaranteed by any means - it invokes undefined behaviour.
If you try to acces the memory, /anything/ can happen.
so in my case j should still point to that
memory right ? Right, but see above.

MC
Irrwahn
 
E

Eric Sosman

MC said:
Hi
I have the following piece of code.

int *p;
p = malloc(10);
int *j;
j = p;
free(p);

Is this legal ?

In C99, yes. In C89, no: executable statements cannot
precede declarations. But a simple rearrangement makes it
legal in C89, too:

int *p;
int *j;
p = malloc(10);
j = p;
free (p);
will j still point to the same
memory that p pointed to earlier ?

No. More precisely, "It's impossible for a conforming
program to find out," meaning that any attempt to find out
invokes undefined behavior.
Can I access that memory using j ?

No. Build a house; that's the malloc() call. Write
down its address on a slip of paper called `p'. Make a
photocopy of that slip of paper and call it `j'. Give
`p' to your friendly local arsonist and have him burn
down the house at the indicated address. The fact that
you've still got `j' in your pocket doesn't mean the
burned-out house is habitable.
I read somewhere that even though free is
called, the memory is still available.

I read somewhere that the Earth is flat.
so in my case j should still point to that
memory right ?

It's impossible to tell. Try to use the memory `j'
formerly pointed to (it's been burned, remember?) and there's
no telling what might happen.

Recommended reading: Section 7 of the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
 
D

djinni

Hi
I have the following piece of code.

int *p;
p = malloc(10);
int *j;
j = p;
free(p);

Is this legal ? will j still point to the same
memory that p pointed to earlier ?
Can I access that memory using j ?

I read somewhere that even though free is
called, the memory is still available.
so in my case j should still point to that
memory right ?

MC

[ from the FAQ ]
--------------------------------------------------------------------
7.20: You can't use dynamically-allocated memory after you free it,
can you?

A: No. Some early documentation for malloc() stated that the
contents of freed memory were "left undisturbed," but this ill-
advised guarantee was never universal and is not required by the
C Standard.

Few programmers would use the contents of freed memory
deliberately, but it is easy to do so accidentally. Consider
the following (correct) code for freeing a singly-linked list:

struct list *listp, *nextp;
for(listp = base; listp != NULL; listp = nextp) {
nextp = listp->next;
free(listp);
}

and notice what would happen if the more-obvious loop iteration
expression listp = listp->next were used, without the temporary
nextp pointer.

References: K&R2 Sec. 7.8.5 p. 167; ISO Sec. 7.10.3; Rationale
Sec. 4.10.3.2; H&S Sec. 16.2 p. 387; CT&P Sec. 7.10 p. 95.

7.21: Why isn't a pointer null after calling free()?
How unsafe is it to use (assign, compare) a pointer value after
it's been freed?

A: When you call free(), the memory pointed to by the passed
pointer is freed, but the value of the pointer in the caller
probably remains unchanged, because C's pass-by-value semantics
mean that called functions never permanently change the values
of their arguments. (See also question 4.8.)

A pointer value which has been freed is, strictly speaking,
invalid, and *any* use of it, even if is not dereferenced, can
theoretically lead to trouble, though as a quality of
implementation issue, most implementations will probably not go
out of their way to generate exceptions for innocuous uses of
invalid pointers.

References: ISO Sec. 7.10.3; Rationale Sec. 3.2.2.3.
===================================================================


Hope this helps,

-dj
 
J

Joona I Palaste

In C99, yes. In C89, no: executable statements cannot
precede declarations. But a simple rearrangement makes it
legal in C89, too:
int *p;
int *j;
p = malloc(10);
j = p;
free (p);
No. More precisely, "It's impossible for a conforming
program to find out," meaning that any attempt to find out
invokes undefined behavior.
No. Build a house; that's the malloc() call. Write
down its address on a slip of paper called `p'. Make a
photocopy of that slip of paper and call it `j'. Give
`p' to your friendly local arsonist and have him burn
down the house at the indicated address. The fact that
you've still got `j' in your pocket doesn't mean the
burned-out house is habitable.

A further comment about this...

#include <stdlib.h>
int main(void) {
char *p = malloc(100);
if (p != NULL) {
free(p);
p; /* ILLEGAL! */
p = NULL; /* entirely legal;
}
return 0;
}

This is because using the value of a freed pointer, if it's not
NULL, in any context whatsoever, is undefined behaviour. Using
the freed pointer itself to assign it a new value, though, is
legal.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"It sure is cool having money and chicks."
- Beavis and Butt-head
 
M

Martin Dickopp

Pieter Droogendijk said:
Sure it is.

This is not guaranteed by the standard. A conforming implementation would
be free to return the memory, and even the address space, to the under-
lying operating system.

So while the memory is certainly no longer available to the application,
it might even cease to exist when `free' is called.
Seriously, once you free() a malloced chunk, dereferencing the pointer
leads to undefined behaviour.

Not only dereferencing the pointer, but *any* use of the pointer value
might lead to undefined behavior.

Martin
 
S

Simon Biber

Martin Dickopp said:
This is not guaranteed by the standard. A conforming
implementation would be free to return the memory, and even
the address space, to the under-lying operating system.

C99 7.20.3.2#2 "The free function causes the space pointed
to by ptr to be deallocated, that is, made available for
further allocation."

If it's given back to the operating system, there would be no
guarantee it will be "made available for further allocation."
Not only dereferencing the pointer, but *any* use of the
pointer value might lead to undefined behavior.

Can you print it with printf("%p\n", (void*)p);? Or is the
conversion to (void*) invalid for an invalid pointer value?

At the least you should be able to look at its bytes through
a pointer to unsigned char.
 
E

Eric Sosman

Simon said:
C99 7.20.3.2#2 "The free function causes the space pointed
to by ptr to be deallocated, that is, made available for
further allocation."

If it's given back to the operating system, there would be no
guarantee it will be "made available for further allocation."


Can you print it with printf("%p\n", (void*)p);? Or is the
conversion to (void*) invalid for an invalid pointer value?

No and yes, respectively. After the free(), the pointer
value becomes indeterminate (6.2.4, paragraph 2). Note that
"becomes indeterminate" does not necessarily imply a change
of representation; the bits in the pointer object before and
after the free() may be identical. The value is indeterminate
anyhow -- the example often given is of an architecture whose
pointers include a tag of some sort referencing a piece of the
hardware environment; change that hardware environment as part
of the free() operation, and the tag bits that used to mean
something now mean nonsense.
At the least you should be able to look at its bytes through
a pointer to unsigned char.

Yes, this is fine. There's no contradiction, because byte-
by-byte inspection makes no use of the pointer value, just as
byte-by-byte inspection of floating-point object that happens
to contain a signalling NaN makes no use of the f-p value.
Byte-by-byte inspection looks at the representation of an
object, but not at its value.
 
M

Martin Dickopp

[Note to comp.std.c readers: This is a discussion in comp.lang.c about
whether a conforming implementation may return memory deallocated with
`free' to an underlying operating system. I'm cross-posting as the
discussion now touches a question of how to interpret the standard
and/or whether there is a defect in the standard.]

Simon Biber said:
C99 7.20.3.2#2 "The free function causes the space pointed
to by ptr to be deallocated, that is, made available for
further allocation."

If it's given back to the operating system, there would be no
guarantee it will be "made available for further allocation."

I think this does not necessarily mean "made available for further
allocation by the currently running process."

If it does, I would call that a defect. Think of a program which runs in
a multi-process environment and requires a large amount of memory for a
short time. I would certainly hope that it is not the intention of the
standard committee that a conforming implemention is /forbitten/ from
making the memory available to other processes after it is deallocated.
Can you print it with printf("%p\n", (void*)p);?

No. According to 6.2.4#2, "[t]he value of a pointer becomes indeterminate
when the object it points to reaches the end of its lifetime." 3.17.2
defines an "indeterminate value" as "either an unspecified value or a trap
representation", and 6.2.6.1#5 explains that if a trap representation "is
read by an lvalue expression that does not have character type, the
behavior is undefined."
At the least you should be able to look at its bytes through a pointer
to unsigned char.

Yes, that doesn't access the value, but the representation of the pointer.
You can always access the representation of an object.

Martin
 
D

Default User

Eric Sosman wrote:
No. Build a house; that's the malloc() call. Write
down its address on a slip of paper called `p'. Make a
photocopy of that slip of paper and call it `j'. Give
`p' to your friendly local arsonist and have him burn
down the house at the indicated address. The fact that
you've still got `j' in your pocket doesn't mean the
burned-out house is habitable.


Better analogy. You were renting the house, then gave up the lease. Now,
maybe somebody else lives there, maybe it's a crack house and you get
shot walking up to the door, maybe it got leveled for a new mall, maybe
it's empty and it SEEMS like you can use like old times, then the new
owners come home . . .




Brian Rodenborn
 
D

Douglas A. Gwyn

Martin said:
[Note to comp.std.c readers: This is a discussion in comp.lang.c about
whether a conforming implementation may return memory deallocated with
`free' to an underlying operating system. I'm cross-posting as the
discussion now touches a question of how to interpret the standard
and/or whether there is a defect in the standard.]

Actually the committee has already discussed this question.
The returned addresses are in principle available for later
reallocation, but there is of course no requirement that
the program will ever see that region again. It *might*
see it. The reason this is mentioned at all is merely as a
warning that the same pointer values might be obtained from
separate allocations with nonoverlapping lifetimes; but a
strictly conforming program can detect that only by
examining the pointer representations (e.g. as array of
unsigned char), not their values (since the earlier value
has become indeterminate as a result of free()ing).
 
M

Martin Dickopp

Douglas A. Gwyn said:
Martin said:
[Note to comp.std.c readers: This is a discussion in comp.lang.c about
whether a conforming implementation may return memory deallocated with
`free' to an underlying operating system. I'm cross-posting as the
discussion now touches a question of how to interpret the standard
and/or whether there is a defect in the standard.]

Actually the committee has already discussed this question.
The returned addresses are in principle available for later
reallocation, but there is of course no requirement that
the program will ever see that region again. It *might*
see it.

Thank you for the clarification.

Martin
 
A

Andrei Voropaev

The value of p is indeterminate.
You can't say anything else about the value of p
at that point in code.

Are you sure? :) p won't change since it is passed by value into
function and the function can't modify p. So p stays exactly the same as
before call to 'free' :) *p might change of course.
 
M

Martin Dickopp

Andrei Voropaev said:
Are you sure? :)

I'm sure that Pete is sure. :)
p won't change since it is passed by value into function and the
function can't modify p. So p stays exactly the same as before call to
'free' :)

The value of `p' doesn't have to change to become indeterminate. See
6.2.4#2: "[...] The value of a pointer becomes indeterminate when the
object it points to reaches the end of its lifetime."
*p might change of course.

A strictly conforming program cannot examine the value `p'. Specifically,
`*p' is not a valid expression. As undefined behavior goes, it /might/
just yield a changed value, but equally well something completely
different could happen.

Martin
 
K

Karl Heinz Buchegger

Eric said:
No. Build a house; that's the malloc() call. Write
down its address on a slip of paper called `p'. Make a
photocopy of that slip of paper and call it `j'. Give
`p' to your friendly local arsonist and have him burn
down the house at the indicated address. The fact that
you've still got `j' in your pocket doesn't mean the
burned-out house is habitable.

I like that analogy ...
I read somewhere that the Earth is flat.

.... but here you are wrong. The earth is a sphere
and we live on the inner side of the sphere.
Proof: look at your shoes. The tip and the heel
point upwards as expected for an object having
contact with the inner side of a sphere. If we
would live on the outer side, they would point
downward :) :)
 
J

James Kuyper

Pieter Droogendijk said:
int *p;
p = malloc(10);
int *j;
Is illegal in C;

Not under the current C standard. See section 6.8.2:

"Syntax
1 compound-statement:
{ block-item-listopt }

block-item-list:
block-item
block-item-list block-item

block-item:
declaration
statement
"

The restriction that all declarations in a given block had to preceed
all of the statements in that block was removed in C99.
 
S

Simon Biber

pete said:
The value of p is indeterminate.
You can't say anything else about the value of p
at that point in code.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
int i;
void *p = malloc(1);
unsigned char initial[sizeof p], final[sizeof p];

memcpy(initial, &p, sizeof p);
free(p);
memcpy(final, &p, sizeof p);
for(i = 0; i < sizeof p; i++)
if(initial != final)
printf("The value changed\n");
return 0;
}

1. Does this program have undefined behaviour?
2. Can it ever output "The value changed\n"?
 
P

pete

Simon said:
pete said:
The value of p is indeterminate.
You can't say anything else about the value of p
at that point in code.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
int i;
void *p = malloc(1);
unsigned char initial[sizeof p], final[sizeof p];

memcpy(initial, &p, sizeof p);
free(p);
memcpy(final, &p, sizeof p);
for(i = 0; i < sizeof p; i++)
if(initial != final)
printf("The value changed\n");
return 0;
}

1. Does this program have undefined behaviour?
2. Can it ever output "The value changed\n"?


The value of an object is determined not only by the bit pattern,
but also by the type of the identifier used to access it.
It was pointer value, wasn't it ?


#include <stdio.h>

int main(void)
{
signed char object = -1;

if (*(signed char*)&object != *(unsigned char*)&object) {
puts("Is the value of object unequal to the value of object?");
}
return 0;
}


Inequality of bit patterns,
doesn't even imply inequality for pointers.
Despite your crafted string, all that your program does,
is determine whether the bit pattern has changed.
 

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

No members online now.

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,206
Latest member
Zenden

Latest Threads

Top