malloced union member

R

rohit

Hi,

Iam confused as to when is the memory freed in this program.

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

union test{
char *i;
char *ch;
};

int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.i);
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

return 0;
}

And the output I get from my solaris box is :
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

regards
rohitash
 
R

Richard Bos

Iam confused as to when is the memory freed in this program.

union test{
char *i;
char *ch;
};

int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.i);

It is free()d here...
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

....so this statement invokes undefined behaviour.
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

Yes, appearing to work as "normal" is one of the legal results of
undefined behaviour. Should you now be tempted to abuse this feature,
beware! Appearing to work as normal on your testing machines but
crashing spectacularly on your customer's network is _also_ a legal
result of UB...

Richard
 
S

Stephen L.

rohit said:
Hi,

Iam confused as to when is the memory freed in this program.

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

union test{
char *i;
char *ch;
};

int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.i);

Why are you `free()'ing "test.i" here?
You allocated the memory to "test.ch"
(even though both elements of the union
happen to contain the same pointer value,
that's a very bad practice).
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);

You got lucky here. You've `free()'d the same
pointer value _twice_. You've corrupted your heap.
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

return 0;
}

And the output I get from my solaris box is :
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

regards
rohitash

It looks like you're expecting the call to `free()'
to somehow change the contents of the object the
pointer was pointing to, or even the pointer itself.
The value of a pointer after a call to `free()'
is indeterminate.

In this particular case, you were able to dereference
the pointer and it still contained your original
value. This is dumb luck.

To answer your question, the memory obtained by
a call to `malloc()' is "free" at the point of entry
into the call to `free()'. "free" is a non-specific
term, however, and should be taken to mean that it
is not "free" for your program to access any longer.
Some architectues may generate an error accessing
the memory through that pointer, some may do nothing,
and some may give the _appearence_ that the memory
is still valid and contains valid data (as on your
Solaris box).


HTH,

Stephen
 
R

Richard Bos

Stephen L. said:
rohit said:
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);

You got lucky here. You've `free()'d the same
pointer value _twice_. You've corrupted your heap.

You don't know this. It invokes undefined behaviour; this _may_ mean
corrupting his heap, but it may also mean ignoring the statement,
crashing with a segmentation fault, or mailing his resume to
(e-mail address removed).

Richard
 
S

Stephen L.

Richard said:
Stephen L. said:
rohit said:
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);

You got lucky here. You've `free()'d the same
pointer value _twice_. You've corrupted your heap.

You don't know this. It invokes undefined behaviour; this _may_ mean
corrupting his heap, but it may also mean ignoring the statement,
crashing with a segmentation fault, or mailing his resume to ...

Richard

man malloc(3c) for details.

Posters who have identified this behavioral
aspect of `free()' have usually noted it by stating
that their (next) `malloc()'/`free()' core dumps.

The second call to `free()' with the same pointer
value as before qualifies as a "random" value.

"Undefined results will occur if the space assigned by
malloc() is overrun or if some random number is
passed to free()."

-Solaris 8 man page

It _doesn't_ say, "and BTW, the heap is fine."
A reasonable and valid conclusion based on the facts
as presented in the man page (along with other sources)
is that the heap, after a `free()'ing the same
pointer twice, is not usable, even if `free()'
seemed to return okay. I see nothing in the man
page(s) which would bring me to any of the
conclusions you've arrived at - why are posters
trying to DEFINE undefined behavior?

I think it's important to try to answer the OP's
question at the level (not in a condescending manner)
that it is asked. The OP didn't say he was using
any special implementation of `malloc()' (there
are versions out there that perform allocation
using much more sophisticated rules and memory models),
so it was reasonable to assume he was using the
"standard malloc-from-the-heap implementation".
If I was wrong, I'd expect the OP to repost
with a clarification - that's how the dialog
should continue.

But providing garbage answers like "mailing his
resume to ..." really hurt the credibility of
the group as a whole, IMHO.


Stephen
 
D

Dan Pop

In said:
[email protected] (rohit) said:
Iam confused as to when is the memory freed in this program.

union test{
char *i;
char *ch;
};

int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.i);

It is free()d here...

Nope, this call merely invokes undefined behaviour.

Dan
 
D

Dan Pop

In said:
Iam confused as to when is the memory freed in this program.

What else could you expect from a bogus program?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

union test{
char *i;
char *ch;
};

What is the point of this union?
int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

Undefined behaviour: you can't evaluate test.i after initialising test.ch
as they have incompatible types that can't be aliased.
free(test.i);

Undefined behaviour, for the same reason as above.
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

Undefined behaviour.
free(test.ch);

Undefined behaviour. This call would have been correct as the *first*
free call. Now, it is too late...
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

Undefined behaviour.
return 0;
}

And the output I get from my solaris box is :
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

There is no way to get any enlightment from the output of a meaningless
program. Instead of wasting your time writing and executing junk code,
read the FAQ!

Dan
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dan Pop wrote:
| In <[email protected]> (e-mail address removed)
(rohit) writes:
|
|
|>Iam confused as to when is the memory freed in this program.
|
|
| What else could you expect from a bogus program?
|
|
|>#include <stdlib.h>
|>#include <stdio.h>
|>#include <string.h>
|>
|>union test{
|> char *i;
|> char *ch;
|>};
|
|
| What is the point of this union?
|
|
|>int main()
|>{
|> union test test;
|> test.ch = malloc(6);
|> strcpy(test.ch,"hello");
|> printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
|>[%p]\n",test.i,test.ch,test.i,test.ch);
|
|
| Undefined behaviour: you can't evaluate test.i after initialising test.ch
| as they have incompatible types that can't be aliased.

Dan, I'm confused.

Given the OP's union, I don't understand how test.i and test.ch can have
"incompatable types that can't be aliased".

AFAICT, test.i is a pointer to char, and test.ch is a pointer to char. To me,
those don't look like "incompatable types".

Did I read something wrong? Could you clear up my misunderstanding?



[snip]

- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFArBfkagVFX4UWr64RAsM8AJ4gHH989fW30y+lOcUSGEJEULytjgCeNOQ8
8O8w2bmyTSUPcpD6qVJYaAk=
=u+rD
-----END PGP SIGNATURE-----
 
N

Neil Kurzman

rohit said:
Hi,

Iam confused as to when is the memory freed in this program.

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

union test{
char *i;
char *ch;
};

int main()
{
union test test;
test.ch = malloc(6);
strcpy(test.ch,"hello");
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.i);
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);

return 0;
}

And the output I get from my solaris box is :
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

regards
rohitash

The memory is "freed" when you call free(). free() lets the system know
that the memory is not used. It does not have to erase it. So you can
still look at it (on you system). But other systems may not let you look
at memory you do not own. freeing memory you do not own is never good.
it is a good idea to set you pointers to NULL after free() you can then
check them for NULL to insure you do not use pointers that no loner
pointing to memory you own.
 
D

Dan Pop

In said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dan Pop wrote:
| In <[email protected]> (e-mail address removed)
(rohit) writes:
|
|
|>Iam confused as to when is the memory freed in this program.
|
|
| What else could you expect from a bogus program?
|
|
|>#include <stdlib.h>
|>#include <stdio.h>
|>#include <string.h>
|>
|>union test{
|> char *i;
|> char *ch;
|>};
|
|
| What is the point of this union?
|
|
|>int main()
|>{
|> union test test;
|> test.ch = malloc(6);
|> strcpy(test.ch,"hello");
|> printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
|>[%p]\n",test.i,test.ch,test.i,test.ch);
|
|
| Undefined behaviour: you can't evaluate test.i after initialising test.ch
| as they have incompatible types that can't be aliased.

Dan, I'm confused.

Given the OP's union, I don't understand how test.i and test.ch can have
"incompatable types that can't be aliased".

AFAICT, test.i is a pointer to char, and test.ch is a pointer to char. To me,
those don't look like "incompatable types".

Did I read something wrong? Could you clear up my misunderstanding?

My mistake, I interpreted test.ch as having the type pointer to char and
test.i pointer to int, despite the fact that I have actually looked at the
union definition....

Dan
 
R

Richard Bos

Stephen L. said:
Richard said:
Stephen L. said:
rohit wrote:
printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
[%p]\n",test.i,test.ch,test.i,test.ch);
free(test.ch);

You got lucky here. You've `free()'d the same
pointer value _twice_. You've corrupted your heap.

You don't know this. It invokes undefined behaviour; this _may_ mean
corrupting his heap, but it may also mean ignoring the statement,
crashing with a segmentation fault, or mailing his resume to ...

man malloc(3c) for details.

Your particular system's manual pages are immaterial. This is
comp.lang.c, not comp.lang.stephen-l-s-system.manpage.c. Just because
_your_ system defines that using free() on an already free()d pointer
corrupts "your heap", that doesn't mean you can assume all systems do.
Posters who have identified this behavioral
aspect of `free()' have usually noted it by stating
that their (next) `malloc()'/`free()' core dumps.

Note: _usually_.
"Undefined results will occur if the space assigned by
malloc() is overrun or if some random number is
passed to free()."

_Exactly_. _Undefined_ results. _Not_ "the heap will be corrupted".
It _doesn't_ say, "and BTW, the heap is fine."

Neither does it say "and the heap will be corrupted", but that is what
you claimed would happen. It _may_ happen. It _may_ also mail a love
letter to your supervisor.
page(s) which would bring me to any of the
conclusions you've arrived at - why are posters
trying to DEFINE undefined behavior?

I don't know. _You_ are the one trying to do so, by claiming that it
_will_ corrupt the heap. I merely pointed out that undefined behaviour
means that you don't even know that this is true.
But providing garbage answers like "mailing his
resume to ..." really hurt the credibility of
the group as a whole, IMHO.

I'm so sorry. Could you please provide a quote from the Standard (note:
_not_ your system-specific man pages) which shows me the error of my
ways, by stating that undefined behaviour may _not_ result in a resume
being mailed?

Richard
 

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,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top