473,396 Members | 1,748 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

...malloc ...from Rome :-)

Hi all..i'm here another time..for a simple question:

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

int main(void)
{
/*
** I know that someone else use different malloc
** instruction
*/

int *pInt=(int*)malloc(1*sizeof(pInt));

if(pInt)
{
printf("Memory allocated SUCCESS [%p]\n",pInt);
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);

/*
** Why i can see the same address once that i've released?
*/

return 0;
}

Thanks all and have a nice day(???)...

Nov 14 '05 #1
58 3853
"lasek" <cl**************@acrm.it> writes:
Hi all..i'm here another time..for a simple question:

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

int main(void)
{
/*
** I know that someone else use different malloc
** instruction
*/

int *pInt=(int*)malloc(1*sizeof(pInt));

if(pInt)
{
printf("Memory allocated SUCCESS [%p]\n",pInt);
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);

/*
** Why i can see the same address once that i've released?
*/


The addres will not be removed by free(), only the memory pInt points to
will be freed after the call. It can even happen, that you can access
the memory which was already freed, but this depends on the operatin
system.

Kind regrads,
Nicolas

--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nov 14 '05 #2
In article
<97******************************@localhost.talkab outprogramming.com>,
"lasek" <cl**************@acrm.it> wrote:
Hi all..i'm here another time..for a simple question:

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

int main(void)
{
/*
** I know that someone else use different malloc
** instruction
*/

int *pInt=(int*)malloc(1*sizeof(pInt));
This is bogus -- the (int*) cast is unneeded, and the sizeof()
expression is wrong. It should be:

int *pInt = malloc(1 * sizeof (*pInt));

if(pInt)
{
printf("Memory allocated SUCCESS [%p]\n",pInt);
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);


This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().

Cheers,
- jonathan
Nov 14 '05 #3
> This is bogus -- the (int*) cast is unneeded, and the sizeof()
expression is wrong. It should be:

int *pInt = malloc(1 * sizeof (*pInt));

if(pInt)
{
printf("Memory allocated SUCCESS [%p]\n",pInt);
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);


This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().


Actually its not.

if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.

Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true. Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.

James

--
--------------------------
Mobile: +44 07779080838
http://www.stev.org
3:00pm up 1 day, 23:42, 5 users, load average: 0.03, 0.01, 0.00

Nov 14 '05 #4
James Stevenson <ja***@stev.org> spoke thus:
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.


That is, strictly speaking, incorrect. See

http://www.eskimo.com/~scs/C-faq/q7.21.html

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #5
James Stevenson wrote:
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true. Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


1) The value of a pointer variable after a call to free is
indeterminate.
2) Evaluating a variable with a indeterminate value is undefined.

This might seem strange, but the standard is quite clear about
both points above. Can't dig out the quotes just now, but unless
someone else posts them I'll do it later today or tomorrow.

There was a big discussion about this some time ago, maybe google
will have some details.

--
Thomas.
Nov 14 '05 #6
James Stevenson <ja***@stev.org> writes:
This is bogus -- the (int*) cast is unneeded, and the sizeof()
expression is wrong. It should be:

int *pInt = malloc(1 * sizeof (*pInt));

> if(pInt)
> {
> printf("Memory allocated SUCCESS [%p]\n",pInt);
> free(pInt);
> }
>
> printf("Release memory previously allocated [%p]\n",pInt);
This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().


Actually its not.


Actually it is.
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.
No, accessing the value of p after free(p) invokes undefined behavior.
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true. Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


The value doesn't necessarily change (in fact I would argue that the
value, or at least its representation, *can't* change), but the value
becomes indeterminate. On most real-world systems, the resulting
undefined behavior is harmless (the worst kind), but it's
theoretically possible that, for example, an attempt to load the value
into an address register will cause a trap.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
In article <news:Pi*************************************@beas t.stev.org>
James Stevenson <ja***@stev.org> wrote:
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.
The Standard says otherwise.
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true. Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.
Well, sort of.

The *bit pattern* stored in p will not be changed -- but the *value*
of p might change.

Here is a News Rerun.

From: Chris Torek <no****@torek.net>
Newsgroups: comp.lang.c
Subject: Re: Malloc/Free - freeing memory allocated by malloc
Date: 23 Sep 2004 01:01:48 GMT
Message-ID: <ci*********@news2.newsguy.com>
References: <c4**************************@posting.google.com > <c4**************************@posting.google.com > <2r*************@uni-berlin.de> <ci**********@newshost.mot.com>
Je***********@physik.fu-berlin.de wrote: [after]
int *x = malloc( 100 * sizeof *x );
....
free( x );

Both the following lines would invoke undefined behavior.

printf( "%d %d\n", x[ 11 ], *( x + 42 ); /* wrong! */
printf( "%p\n", ( void * ) x ); /* wrong! */


In article <news:ci**********@newshost.mot.com>
Jason Curl <j.****@motorola.com> wrote:I have a question about this [second] line, printing the value of 'x'.
Why is this wrong? The memory allocated [for] x is on the function stack,
and I didn't believe you are accessing any invalid memory region?


Let me back things up a bit. Suppose instead of "int *x" or even
"int y", or "float z", I tell you only that I have four bytes in
memory that are set to 0x12, 0x34, 0x56, and 0x78 in sequence.

What is the value stored in this four-byte region? Is it 0x12345678?
Is it perhaps 0x78563412? Or could it even be something like
17378244361449504001963252426735616.0?

The answer is: it depends. Those four bytes are, as a 32-bit int,
the first value (0x12345678) on a SPARC or 680x0-based machine,
but the second (0x78563412) on an Intel x86-based machine. The
third (1.73782e34, or 7019017 * pow(2,91)) occurs if those four
bytes are meant to be interpreted as a 32-bit floating point number
on the x86.

Clearly, then, the value of some sequence of bytes depends on the
*interpretation* of that byte-sequence. The next question I would
like to ask, then, is this: How are the bytes making up a pointer
interpreted?

On many machines, they happen to be interpreted in precisely the
same way as some integer; but this is not the only possible
interpretation. Those who used the x86 in its early 80186 and
80286 incarnations should remember the "1-megabyte pointer", in
which the upper 16 bits represented the top 16 of the 20 bits of
the address, and the lower 16 bits represented the bottom 16 of
the 20 bits of the address, with those two values being summed:

real_20_bit_address = ((upper_16(ptr) << 4) + lower_16(ptr)) & 0xfffff;

(This means that any given physical address has lots of different
32-bit values that refer to it. This particular "feature" was the
source of a lot of problems and the term "pointer normalization".
It is also one reason that the C standards define "a < b" only for
pointers a and b into a single object, while "a == b" is defined
even if a and b point to different objects -- the equality operators
must normalize their pointers, while the relational operators are
allowed to compare only the offsets.)

Yet another interpretation was allowed on some varieties of the
x86, in which the upper 16 bits of the pointer were an index into
an (external) table, and the lower 16 bits were an offset to be
applied to the result of the table:

real_NN_bit_address = table[upper_16(ptr)] + lower_16(ptr);
/* more or less */

All of these interpretations -- and indeed almost any other
interpretation anyone can think of yesterday, today, or tomorrow
-- are allowed (but not required) by the C standard. The last of
the above, with the table-lookup step, happens to allow something
else the x86 did: the table need not contain just a "base address".
It can also contain a "valid" flag:

if (table[upper_16(ptr)].valid == 0)
throw_runtime_error("invalid address");
real_NN_bit_address = table[upper_16(ptr)].base + lower_16(ptr);

Now, all free() needs to do is contain, as one of its steps:

table[upper_16(ptr)].valid = 0;

and suddenly a bit pattern that *was* valid, before the call to
free(), is no longer valid. An attempt to print it, which used
to work, may now cause a runtime "invalid address" error.

The bit pattern has not changed. What changed is the external
table. The C standard allows this, and tells you -- the C programmer
-- not to attempt to use the value in x after passing that value
to free(), just in case free() cleared the table's "valid" bit.

Of course, as Jens wrote, you *are* allowed to overwrite x with a
new value, or with NULL. Any C compiler must make sure this works,
even if it has this kind of "valid/invalid table entry" action that
goes on with malloc() and free().

This is all part of a more fundamental issue, which C programmers
in particular should consider, because C has "C bytes" that can be
used to access hardware-level "representations" instead of
language-level "values". That issue is: the *representation* of
a value, and value itself, are different things. Values arise
through *interpretation* of some bit pattern (a "representation"),
and the process of interpretation can be quite complex. We see
this now, today, on conventional architectures, only in floating-point
numbers -- but in the past, we saw such things elsewhere. There
were good reasons for complicated interpretations for pointers,
and those reasons may well recur in the future.

["Methods of interpretation" are also the reason we see byte-order
issues in integers. If some entity takes a long string of bits
and breaks it up into groups of, say, 8 at a time, it is that entity
that chooses which order to put out the groups, and then to
re-assemble them for later re-interpretation as a larger group.
Any given machine may have its own method(s) for splitting and
combining to get 8-bit groups, but if you, as a C programmer, deal
in terms of (integral) *values*, and do your own splitting and
combining, *you* can control the results, rather than being at the
mercy of your machine(s).]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #8
post...in effect before post this question, it should be better to read
others post..

The post from Chris Torek is very exaustive...

But now i've another doubt:

if i have an expression like this:

struct agenda
{
char acNome[20];
struct agenda *next;
};

typedef struct agenda lista_agenda;

lista_agenda *start=NULL;

start=(lista_agenda *)malloc(sizeof(lista_agenda));

/*
** void *malloc(size_t size);
*/
...i need to cast the result from malloc and i don't need to put the
operator '*' inside the sizeof [sizeof(lista_agenda*)]...because i need a
pointer variable to point to a "lista_agenda type".Because if i put the
'*'..with gdb i see a crash when try to strncpy the first members:
"Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6"

Is correct ?.

Best regards from Rome.
Nov 14 '05 #9

"James Stevenson" <ja***@stev.org> wrote in message
news:Pi*************************************@beast .stev.org...
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);
This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().


Actually its not.

if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.


I used to believe that too -- until I came to clc and
the kind folks here straightened me out. :-)
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true.
No, in itself that's not necessarily true. What *is* true
is that the standard specifically states that the result
of evaluating its value is undefined behavior.
Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.

-Mike
Nov 14 '05 #10
"lasek" <cl**************@acrm.it> wrote in message
news:7c******************************@localhost.ta lkaboutprogramming.com...
post...in effect before post this question, it should be better to read
others post..

The post from Chris Torek is very exaustive...
Yes, and sometimes I find reading his stuff to
be exhausting :-), but always worthwhile.
But now i've another doubt:

if i have an expression like this:

struct agenda
{
char acNome[20];
struct agenda *next;
};

typedef struct agenda lista_agenda;

lista_agenda *start=NULL;

start=(lista_agenda *)malloc(sizeof(lista_agenda));
Stop doing that (casting return value of 'malloc()').
It only can serve to hide a serious error (omitting
'malloc()'s declaration).

#include <stdlib.h> /* make sure this is at the beginning of your file */
/* etc */
start = malloc(sizeof *start);

/*
** void *malloc(size_t size);
*/
..i need to cast the result from malloc
No, you do *not*.
and i don't need to put the
operator '*' inside the sizeof [sizeof(lista_agenda*)]
The expression 'sizeof(lista_agenda*)' will give the
number of bytes occupied by a pointer (specifically the
size of type 'lista_agenda *'). Not the size of 'struct
agenda'.
...because i need a
pointer variable to point to a "lista_agenda type".
'malloc()' returns a pointer to the allocated memory.
Assign it (directly) to 'start'. Then it does indeed
point to an (uninitialized) object of type 'struct agenda'.
No cast is needed. A pointer to void can be converted to
any other pointer type (and back again if desired). The
language standard specifically states this.
Because if i put the
'*'..with gdb i see a crash when try to strncpy the first members:
"I put the '*'", is not specific enough to describe
exactly what you're doing.
"Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6"
Show us the *exact* code that produces this behavior.

Is correct ?.
No.

Best regards from Rome.


Um, it seems today I should not "do as the Romans do." :-)

-Mike
Nov 14 '05 #11

On Mon, 18 Oct 2004, Christopher Benson-Manica wrote:
James Stevenson <ja***@stev.org> spoke thus:
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.


That is, strictly speaking, incorrect. See

http://www.eskimo.com/~scs/C-faq/q7.21.html


erm thats for the resource it just backs up my statement.

Quote:

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?

The contents of p are still valid where the contents of where p point are
no unpredictable. Hence p is still completly valid.

as in

func() {
int *p = malloc(sizeof(*p));
if (!p)
bomb();
free(p);
p = (int *) 0;
}

Is perfrectly valid to write.
however *p = 0; after the free would be of course dangerour and
unpredicatable.

The local variable p as a point is not changed by free in any way.

James

--
--------------------------
Mobile: +44 07779080838
http://www.stev.org
8:50pm up 2 days, 5:32, 4 users, load average: 0.00, 0.00, 0.00

Nov 14 '05 #12
On Mon, 18 Oct 2004 12:30:22 -0400, in comp.lang.c , "lasek"
<cl**************@acrm.it> wrote:
But now i've another doubt:

start=(lista_agenda *)malloc(sizeof(lista_agenda));

..i need to cast the result from malloc
No you don't,. A C compiler is obliged to ensure that the memory returned
by malloc automatically matches the type you assign it to.
and i don't need to put the
operator '*' inside the sizeof [sizeof(lista_agenda*)]...because i need a
pointer variable to point to a "lista_agenda type".
Yes. To avoid this confusion, use the idiom:

start = malloc(sizeof *start);
Because if i put the
'*'..with gdb i see a crash when try to strncpy the first members:
"Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6"
You have a bug somewhere else in your code. For example, you're corrupting
the memory in your struct, or you're trying to free it twice.
Is correct ?.


No
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #13
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.


I used to believe that too -- until I came to clc and
the kind folks here straightened me out. :-)
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true.


No, in itself that's not necessarily true. What *is* true
is that the standard specifically states that the result
of evaluating its value is undefined behavior.
Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.

Last time i check free was a function not a macro or did i mis something.
but of course the contents of p probably are not usefull in any case after
free has been called :)

James

--
--------------------------
Mobile: +44 07779080838
http://www.stev.org
9:10pm up 2 days, 5:52, 5 users, load average: 0.00, 0.02, 0.00
Nov 14 '05 #14

"James Stevenson" <ja***@stev.org> wrote in message
news:Pi*************************************@beast .stev.org...
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.
I used to believe that too -- until I came to clc and
the kind folks here straightened me out. :-)
Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true.


No, in itself that's not necessarily true. What *is* true
is that the standard specifically states that the result
of evaluating its value is undefined behavior.
Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro


No.
otherwise it has no way of changing the value of p directly.
Note that the language standard does not prohibit 'magic' (or anything
else) as an implementation method. Behavior is what is specified
(or specifically left 'undefined' or 'implementation-defined', etc.)
The 'pass-by-value' semantics of C don't necessarily apply in this
case. This is why the explicit verbiage of the standard.
("or if the space has been deallocated by a call to free or realloc,
the behavior is undefined.")
Last time i check free was a function not a macro or did i mis something.
It's a function (but whose internal operational details are
left to the implementation).
but of course the contents of p probably are not usefull
Not just not useful, not defined. A particular implementation
might choose to define and/or use this "value" in some way, but
such usage falls outside the domain of the standard language/library.
in any case after
free has been called :)


Right. Thus the practice by many of assigning NULL to the pointer
immediately after 'free()' (some wrap 'free' in a macro for this
purpose), so they can inspect its value before subsequent use.
Treat a pointer passed to 'free()' as you would an uninitialized
object, i.e. "no peeking" (but of course you're free :-) to assign
it a new value).
-Mike
Nov 14 '05 #15
James Stevenson <ja***@stev.org> spoke thus:
erm thats for the resource it just backs up my statement.
A careful reading reveals the opposite:

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

The key portion is "even if it is not dereferenced"; IOW, the value of
the pointer may not be used in any way once it has been passed to
free(). Specifically, it may not be passed to the printf as an
argument for the %p conversion specifier, as in the OP's code:

if(pInt)
{
printf("Memory allocated SUCCESS [%p]\n",pInt);
free(pInt);
}

printf("Release memory previously allocated [%p]\n",pInt);

While the FAQ notes that on reasonable implementations it is likely
to be altogether harmless, the code as written exhibits undefined
behavior (as other more learned posters have also pointed out).
Therefore your original statement:

"[i]t is perforectly ok to access p but not ok to access *p after the
free is performed."

is incorrect. Of course, the code you supplied
func() {
int *p = malloc(sizeof(*p));
if (!p)
bomb();
free(p);
p = (int *) 0;
}


is correct; the value of the freed pointer is not used. However, it
does contain an unnecessary cast of 0 to (int *); 0 in a pointer
context is guaranteed to yield the same value as the macro NULL.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #16

"James Stevenson" <ja***@stev.org> wrote in message
news:Pi*************************************@beast .stev.org...

On Mon, 18 Oct 2004, Christopher Benson-Manica wrote:
James Stevenson <ja***@stev.org> spoke thus:
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.
That is, strictly speaking, incorrect. See

http://www.eskimo.com/~scs/C-faq/q7.21.html


erm thats for the resource it just backs up my statement.


Huh?
Quote:

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?

The contents of p are still valid where the contents of where p point are
no unpredictable. Hence p is still completly valid.

as in

func() {
int *p = malloc(sizeof(*p));
if (!p)
bomb();
free(p);
p = (int *) 0;
}

Is perfrectly valid to write.
however *p = 0; after the free would be of course dangerour and
unpredicatable.

The local variable p as a point is not changed by free in any way.


That is not what appears at that URL. This is:
============ begin quote ================================

Question 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?

----------------------------------------------------------------------------
----

When you call free, the memory pointed to by the passed pointer is freed,
but the value of the pointer in the caller 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: ANSI Sec. 4.10.3
ISO Sec. 7.10.3
Rationale Sec. 3.2.2.3
This page by Steve Summit // Copyright 1995

============ end quote ================================
This does seem to indicate that a (valid, evaluable) expression
can switch from 'valid' to 'invalid' without it's 'value' having
changed. The standard appears to allow this, which imo it has every
right to do, being the definition of how things behave (there
are many stated exceptions to certain behaviors scattered throughout).
However the second paragraph does clearly state the actual facts.

Perhaps you're looking at some other 'FAQ' or an older,
incorrect version of this one and failed to refresh your
browser cache?
-Mike
Nov 14 '05 #17
In article <Pi*************************************@beast.ste v.org>,
James Stevenson <ja***@stev.org> wrote:
On Mon, 18 Oct 2004, Christopher Benson-Manica wrote:
James Stevenson <ja***@stev.org> spoke thus:
if you define int *p;
it is perforectly ok to access p but not ok to access *p
after the free is performed.
That is, strictly speaking, incorrect. See

http://www.eskimo.com/~scs/C-faq/q7.21.html


erm thats for the resource it just backs up my statement.

Quote:

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?

The contents of p are still valid where the contents of where p point are
no unpredictable. Hence p is still completly valid.


Read that second question again -- it is talking about the *value* of
the pointer, not what the pointer points at.
as in

func() {
int *p = malloc(sizeof(*p));
if (!p)
bomb();
free(p);
p = (int *) 0;
}

Is perfrectly valid to write.
Yes. No one has said that otherwise (you're overwriting the value of p,
not using it)
however *p = 0; after the free would be of course dangerour and
unpredicatable.
Yes. The standard also says that:

char *q;

free(p);
q = p; /* undefined */
if (p != NULL) /* undefined */
/* ... */

leads to undefined behavior.
The local variable p as a point is not changed by free in any way.


Indeed it isn't. That doesn't mean it is safe to use its value.

Cheers,
- jonathan
Nov 14 '05 #18
James Stevenson <ja***@stev.org> writes:
On Mon, 18 Oct 2004, Christopher Benson-Manica wrote:
James Stevenson <ja***@stev.org> spoke thus:
> if you define int *p;
> it is perforectly ok to access p but not ok to access *p
> after the free is performed.
That is, strictly speaking, incorrect. See

http://www.eskimo.com/~scs/C-faq/q7.21.html


erm thats for the resource it just backs up my statement.


Um, no it doesn't.
Quote:

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?

The contents of p are still valid where the contents of where p point are
no unpredictable. Hence p is still completly valid.
Nope. FAQ 7.21 says:

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 pointer
as in

func() {
int *p = malloc(sizeof(*p));
if (!p)
bomb();
free(p);
p = (int *) 0;
}

Is perfrectly valid to write.
however *p = 0; after the free would be of course dangerour and
unpredicatable.
Yes, the above is perfectly valid, since it doesn't access the value
of p after the call to free().

It's important to distinguish between an object (p in this case) and
the current value of an object. After free(p), p is still a pointer
object, and you can take its address or assign a value to it. You can
do anything that doesn't examine the value stored in p. But if you do
examine its value, you invoke undefined behavior. So the following is
ok:

int *p = malloc(sizeof *p);
free(p); /* valid whether malloc succeeded or not */
p = NULL;

but this is not:

int *p = malloc(sizeof *p);
free(p);
if (p == NULL) ...
The local variable p as a point is not changed by free in any way.


The bits making up the value of p don't change; what changes is
whether the value is indeterminate.

With a few system-specific assumptions:

int *p = malloc(sizeof *p);
/*
* Assume that malloc succeeded, and that the value stored in p
* is represented as 0x12345678; this is the address of the
* allocated memory. (int*)0x12345678 is now a valid pointer
* value.
*/
free(p);
/*
* This informs the system that we're finished with the memory
* allocated by malloc(). It doesn't change the representation of
* the value of p, but that unchanged value has become
* indeterminate. (int*)0x12345678 is now an indeterminate
* pointer value. An attempt to dereference it obviously invokes
* undefined behavior. Less obviously, but just as true, an
* attempt to examine the value, such as (p == NULL), also invokes
* undefined behavior. You can still retrieve the representation
* by aliasing p with an array of unsigned char, but there's
* little reason for doing so.
*/

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #19
Mark McIntyre <ma**********@spamcop.net> writes:
On Mon, 18 Oct 2004 12:30:22 -0400, in comp.lang.c , "lasek"
<cl**************@acrm.it> wrote:
But now i've another doubt:

start=(lista_agenda *)malloc(sizeof(lista_agenda));

..i need to cast the result from malloc


No you don't,. A C compiler is obliged to ensure that the memory returned
by malloc automatically matches the type you assign it to.


It's true that you don't need the cast, but your explanation is a bit
off.

malloc doesn't return the allocated memory, it returns a pointer to
it. The allocated memory is guaranteed to be suitably aligned for any
type of object, but that's not why the cast is unnecessary. The cast
is unnecessary because malloc returns a result of type void*, and a
value of type void* can be implicitly converted to any
pointer-to-object type. (The suitable alignment is what makes the
result useful.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #20
On Mon, 18 Oct 2004 21:03:14 GMT, in comp.lang.c , Keith Thompson
<ks***@mib.org> wrote:
It's true that you don't need the cast, but your explanation is a bit
off.


I prefer "oversimplified".... :-)
But I agree with your correction.

By the way sorry if my posts start appearing multiple times - my news
provider is having some sort of hairy fit and seems to be rejecting but at
the same time accepting some postings. Gah.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #21
On Mon, 18 Oct 2004 21:18:46 +0100, in comp.lang.c , James Stevenson
<ja***@stev.org> wrote:
someone whose attribution James snipped said, talking of free.

It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.


free() is part of the implementation. It can do all sorts of things that're
not allowed by users of the implementation.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #22
James Stevenson wrote: *** And again rudely removed attributes ***
.... snip ...

No, in itself that's not necessarily true. What *is* true
is that the standard specifically states that the result
of evaluating its value is undefined behavior.
Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.

From the FAQ:

A pointer value which has been freed is, strictly speaking,
invalid, and *any* use of it, even if it 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.

That pointer p might signal, on dereference: Wake up the small boy
and send him donw to Joes house to pick up that piece of paper in
the front parlor. Bring it back and read it to me.

Printing the pointer value (via %p) might mean wake up the boy and
have him scream his name.

free may well signal: Send the small boy home for a nights sleep,
and destroy that paper at some future time.

After that the boy is no longer available to scream his name.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Nov 14 '05 #23
"Mike Wahler" <mk******@mkwahler.net> writes:
[...]
This page by Steve Summit // Copyright 1995 [...]
Perhaps you're looking at some other 'FAQ' or an older,
incorrect version of this one and failed to refresh your
browser cache?


I think we can safely assume that he's refreshed his browser cache
some time in the last 9 years. (If he hasn't, that's actually pretty
impressive in its own way.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #24
James Stevenson <ja***@stev.org> wrote:

This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().
Actually its not.

if you define int *p;
it is perforectly ok to access p


p (as well as *p) becomes indeterminate after free() is called.
Accessing of indeterminate values is undefined behaviour (3.18#1).
but not ok to access *p after the free is performed.

Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true.


Actually it is true. After a call to free(), the value passed
in becomes indeterminate. (The representation doesn't change,
obviously, but the value of that representation has changed).
N869 6.2.4 (especially, the second sentence):

[#6] If an object is referred to when storage is not
reserved for it, the behavior is undefined. The value of a
pointer that referred to an object whose storage is no
longer reserved is indeterminate. During the time that its
storage is reserved, an object has a constant address.
Nov 14 '05 #25
On Mon, 18 Oct 2004 12:30:22 -0400, in comp.lang.c , "lasek"
<cl**************@acrm.it> wrote:
But now i've another doubt:

start=(lista_agenda *)malloc(sizeof(lista_agenda));

..i need to cast the result from malloc
No you don't,. A C compiler is obliged to ensure that the memory returned
by malloc automatically matches the type you assign it to.
and i don't need to put the
operator '*' inside the sizeof [sizeof(lista_agenda*)]...because i need a
pointer variable to point to a "lista_agenda type".
Yes. To avoid this confusion, use the idiom:

start = malloc(sizeof *start);
Because if i put the
'*'..with gdb i see a crash when try to strncpy the first members:
"Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6"
You have a bug somewhere else in your code. For example, you're corrupting
the memory in your struct, or you're trying to free it twice.
Is correct ?.


No
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #26
bd
James Stevenson wrote:
> if you define int *p;
> it is perforectly ok to access p but not ok to access *p
> after the free is performed.
I used to believe that too -- until I came to clc and
the kind folks here straightened me out. :-)
> Also what you seem to impliy is that the value of p
> will change once passed to the function free. This is also
> not true.


No, in itself that's not necessarily true. What *is* true
is that the standard specifically states that the result
of evaluating its value is undefined behavior.
>Only the memory address that p points to may / may not be
> changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.


The value doesn't change. It simply ceases to be defined. What this means is
simply:
void *p = malloc(1);
p; /* Defined behavior in the ISO C standard */
free(p);
p; /* Anything can happen here. */
Last time i check free was a function not a macro or did i mis something.
but of course the contents of p probably are not usefull in any case after
free has been called :)

James


Nov 14 '05 #27
On 18 Oct 2004 15:21:27 -0700, ol*****@inspire.net.nz (Old Wolf) wrote
in comp.lang.c:
James Stevenson <ja***@stev.org> wrote:

This provokes undefined behavior -- you may not reference the value of
pInt in any way after it has been passed to free().


Actually its not.

if you define int *p;
it is perforectly ok to access p


p (as well as *p) becomes indeterminate after free() is called.
Accessing of indeterminate values is undefined behaviour (3.18#1).


Perhaps you should spend the money on a copy of the real standard.
N869 is obsolete, and the wording you refer to that specifically
states does not exist in the actual standard. It was removed after
N869. Nowhere in the standard does it state that using the value of
an indeterminate object causes undefined behavior.
but not ok to access *p after the free is performed.

Also what you seem to impliy is that the value of p
will change once passed to the function free. This is also
not true.


Actually it is true. After a call to free(), the value passed
in becomes indeterminate. (The representation doesn't change,
obviously, but the value of that representation has changed).
N869 6.2.4 (especially, the second sentence):

[#6] If an object is referred to when storage is not
reserved for it, the behavior is undefined. The value of a
pointer that referred to an object whose storage is no
longer reserved is indeterminate. During the time that its
storage is reserved, an object has a constant address.


This is more wording that is not in the actual standard. The last
sentence of paragraph 2 of 6.2.4 does say "The value of a pointer
becomes indeterminate when the object it points to reaches the end of
its lifetime."

But as I said, nowhere in the actual standard does it state that
accessing an indeterminate value is undefined.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #28
Hiiiiii....always from Rome....and today the weather is a little
dirt...(like Alice in Chains....);however, i've a little script that
allocate memory for first time when i created the 'agenda':

naturally start is global an it was declared:

struct agenda
{
char acNome[20];
struct agenda *next;
};

typedef struct agenda lista_agenda;

lista_agenda *start=NULL;

void crea_agenda()
{
start=(lista_agenda *)malloc(sizeof(lista_agenda));

if(start!=NULL)
{
memset((char *)start->acNome,'\0',sizeof(start->acNome));

scanf("%s",start->acNome);

start->next=NULL;
}
}

When i insert a new value, i need to add a new node, so:

void inserisci()
{
char newNome[20]={0};
unsigned int iLen;

lista_agenda *newrecord;
lista_agenda *locate;
lista_agenda *localizza(lista_agenda *ptStruct);

printf("\nNew name:");

scanf("%s",newName);

iLen=sizeof(newName);

/*
** this function return a pointer to the last node in
** the list.
*/

locate=localizza(start);

if(newNome)
{
/*
** Now i know that cast the return value from malloc
** is not correct but this is my original code.
*/

newrecord=(lista_agenda *)malloc(sizeof(lista_agenda));

if(newrecord)
{
strncpy(newrecord->acNome,newNome,iLen);

locate->next=newrecord;

newrecord->next=NULL;
}
else
printf("Impossibile allocare lo spazio richiesto.\n");
}
}

The error i receive when i try to add a new node it depends from the
malloc function i use, in particular:

newrecord=(lista_agenda *)malloc(sizeof(lista_agenda));
This line above is ok(from my gdb).
Also because, (i think) i must allocate for the entire size of my struct
and not the size of a pointer to the struct.
(i'm not sure but if i execute a sizeof of a pointer a can see always 4
byte;maybe u'm wrong).

The line below give me an strange error from (gdb):
newrecord=(lista_agenda *)malloc(sizeof(lista_agenda*));

"
Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6
(gdb) where
#0 0x4207aecc in chunk_free () from /lib/i686/libc.so.6
#1 0x4207a60a in chunk_alloc () from /lib/i686/libc.so.6
#2 0x4207a058 in malloc () from /lib/i686/libc.so.6
#3 0x08048790 in ?? ()
#4 0x08048599 in ?? ()
#5 0x42017499 in __libc_start_main () from /lib/i686/libc.so.6
".

Thanks all for your patience...
Nov 14 '05 #29
lasek wrote:
The line below give me an strange error from (gdb):
newrecord=(lista_agenda *)malloc(sizeof(lista_agenda*));


This is the way, that they like to write something like that,
on this newsgroup:

#include <stdlib.h>
newrecord = malloc(sizeof *newrecord);

Don't forget #include <stdlib.h>

--
pete
Nov 14 '05 #30
James Stevenson <ja***@stev.org> wrote:

[ Please stop snipping all attributions - leave those which refer to
text that's still in the post. ]
Only the memory address that p points to may / may not be
changed. The actually value of p will remain constant.


It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.


It needn't change p directly. Even disregarding implementation magic,
what about a function which doesn't change the bit pattern of p, but
does release the segment p refers to from the allocated segment tables?
In that case, p has suddenly changed from "my memory" to "someone else's
memory - there's nothing for me there". Even referring to p's value
could now cause a segmentation violation.

Richard
Nov 14 '05 #31
Jack Klein <ja*******@spamcop.net> writes:
[...]
This is more wording that is not in the actual standard. The last
sentence of paragraph 2 of 6.2.4 does say "The value of a pointer
becomes indeterminate when the object it points to reaches the end of
its lifetime."

But as I said, nowhere in the actual standard does it state that
accessing an indeterminate value is undefined.


But in the case of a freed pointer, I think we can infer that
accessing its value causes undefined behavior.

C99 6.2.4p2:
The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime.

C99 3.17.2:
indeterminate value
either an unspecified value or a trap representation

C99 3.17.3:
unspecified value
valid value of the relevant type where this International Standard
imposes no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation.

C99 6.2.6.1p5:
Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation and is read by an lvalue expression that does not
have character type, the behavior is undefined. If such a
representation is produced by a side effect that modifies all or
any part of the object by an lvalue expression that does not have
character type, the behavior is undefined. Such a representation
is called a _trap representation_.

So after free(p), p has an indeterminate value, which may be either an
unspecified value (which is a valid value of the type) or a trap
representation. If it's a trap representation, accessing the value
invokes undefined behavior; if it's merely unspecified, it doesn't.
An implementation is certainly allowed to make it a trap
representation, and isn't required to document whether it does or not.

I'm not particularly happy with the standard's use of the term
"indeterminate value" here rather than "trap representation". In
effect, accessing p may or may not invoke undefined behavior; this is
indistinguishible from saying that accessing p *does* invoke undefined
behavior. The standard could simply have said that the value of the
pointer becomes a trap representation with, as far as I can tell, no
effect on any implementation.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #32
Jack Klein <ja*******@spamcop.net> wrote:
Old Wolf wrote:

p (as well as *p) becomes indeterminate after free() is called.
Accessing of indeterminate values is undefined behaviour (3.18#1).
Perhaps you should spend the money on a copy of the real standard.


Probably true
N869 is obsolete, and the wording you refer to that specifically
states does not exist in the actual standard. It was removed after
N869. Nowhere in the standard does it state that using the value of
an indeterminate object causes undefined behavior.


What does it say instead (for example how does it deal with the
possibility of an indeterminate value being a trap representation),
and what does C89 have to say?
Nov 14 '05 #33
On Tue, 19 Oct 2004 08:30:38 UTC, "lasek" <cl**************@acrm.it>
wrote:
Hiiiiii....always from Rome....and today the weather is a little
dirt...(like Alice in Chains....);however, i've a little script that
allocate memory for first time when i created the 'agenda':

naturally start is global an it was declared:

struct agenda
{
char acNome[20];
struct agenda *next;
};

typedef struct agenda lista_agenda;

lista_agenda *start=NULL;

void crea_agenda()
{
start=(lista_agenda *)malloc(sizeof(lista_agenda));
invokes clearly undefined behavior when the compiler misses the
prototype of malloc. Then it thinks malloc returns int - and that can
be returned in another was as pinters gets returned - so you converts
something unknown but not a boid* to a pointer to lists_agenda.
casting a return value void* to (all and anything) is ALWAYS and under
any circumstance a bug.
if(start!=NULL)
{
memset((char *)start->acNome,'\0',sizeof(start->acNome));
Using memset to fill anything else as an array of char (or a string)
is undefined behavior too. E.g. filling a pointer with binary 0 bytes
can be an access violation. There is no guarantee that a NULL pointer
has any bits set to 0. It may have padding bits set to nonzer0 to be a
valid pointer. You have NO chance to preset a struct with proper
values as to
a) copy a proper initialised struct (x = y)
or
b) initialise each member of the struct with the proper value.
scanf("%s",start->acNome);
guarantee for hackers to kontaminate your mashine with viruses of any
kind. Don't use scanf or buffer overflow ruins your mashine.

The error i receive when i try to add a new node it depends from the
malloc function i use, in particular:

newrecord=(lista_agenda *)malloc(sizeof(lista_agenda));
clearly undefined behavior - as the compiler has not seen the
prototype of malloc and you assigns something but not the value
returned from malloc to newrecord.
This line above is ok(from my gdb).
No - it's undefined behavior anyway.
Also because, (i think) i must allocate for the entire size of my struct
and not the size of a pointer to the struct.
(i'm not sure but if i execute a sizeof of a pointer a can see always 4
byte;maybe u'm wrong).

The line below give me an strange error from (gdb):
newrecord=(lista_agenda *)malloc(sizeof(lista_agenda*));


It is clearly different! As this will allocate only enough room for a
pointer, but not enough space for a whole struct.

you means clearly
newrecord = malloc(sizeof(*newrecord));

Use the size of the type the target pointer points to is the best way
you can go.

malloc(sizeof lista_agenda) would work too - but lets you change any
occurence of that whenever you changes the type name of that type.

1. #include always the system headers you needs!
2. never cast return values from malloc(), its family or self defined
functions returning void* - to get be warned when you have forgotten
to include the right headers.
3. tell the compiler to serve all, really all possible warnings
4. resolve any warning - but never by simply casting a warning away.
5. mostenly when you things you needs to cast a warning away you are
going on to hide but not resolve the mistake. Double check and recheck
double what you are doing. There is surely no need to cast!
6. whenever you things you needs a cast you are commonly wrong. You've
made another mistake. The simplest would be a missing #include
<something>.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #34
On Tue, 19 Oct 2004, Richard Bos wrote:
James Stevenson <ja***@stev.org> wrote:

[ Please stop snipping all attributions - leave those which refer to
text that's still in the post. ]
>Only the memory address that p points to may / may not be
> changed. The actually value of p will remain constant.

It might, it might not. But that doesn't matter.


then this would dictate that free is not a function but a macro
otherwise it has no way of changing the value of p directly.


It needn't change p directly. Even disregarding implementation magic,
what about a function which doesn't change the bit pattern of p, but
does release the segment p refers to from the allocated segment tables?
In that case, p has suddenly changed from "my memory" to "someone else's
memory - there's nothing for me there". Even referring to p's value
could now cause a segmentation violation.


yeah i can follow that now its kind of like
the old dos problem with far pointers where you end up working on a 16bit
and being able to address more than 64kb of data baecause of the segment
selector. Which used to be called far pointers but c compilers used to
"hide" this functionallity.

I was not aware any processors would have trapped on accessing the value
of an pointer would have cause this to happen.

I assume now the same can also happen with something like this.

int *p;
printf("%p\n");

on the same sorts of system.
James

Nov 14 '05 #35
On Mon, 18 Oct 2004 12:30:22 -0400, in comp.lang.c , "lasek"
<cl**************@acrm.it> wrote:
But now i've another doubt:

start=(lista_agenda *)malloc(sizeof(lista_agenda));

..i need to cast the result from malloc
No you don't,. A C compiler is obliged to ensure that the memory returned
by malloc automatically matches the type you assign it to.
and i don't need to put the
operator '*' inside the sizeof [sizeof(lista_agenda*)]...because i need a
pointer variable to point to a "lista_agenda type".
Yes. To avoid this confusion, use the idiom:

start = malloc(sizeof *start);
Because if i put the
'*'..with gdb i see a crash when try to strncpy the first members:
"Program received signal SIGSEGV, Segmentation fault.
0x4207aecc in chunk_free () from /lib/i686/libc.so.6"
You have a bug somewhere else in your code. For example, you're corrupting
the memory in your struct, or you're trying to free it twice.
Is correct ?.


No
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #36
On Mon, 18 Oct 2004 21:03:14 GMT, in comp.lang.c , Keith Thompson
<ks***@mib.org> wrote:
It's true that you don't need the cast, but your explanation is a bit
off.


I prefer "oversimplified".... :-)
But I agree with your correction.

By the way sorry if my posts start appearing multiple times - my news
provider is having some sort of hairy fit and seems to be rejecting but at
the same time accepting some postings. Gah.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #37
Herbert Rosenau <os****@pc-rosenau.de> spoke thus:
casting a return value void* to (all and anything) is ALWAYS and under
any circumstance a bug.
It's bad practice (as many here have attested), but it is not, in and
of itself, a bug.
scanf("%s",start->acNome);

guarantee for hackers to kontaminate your mashine with viruses of any
kind. Don't use scanf or buffer overflow ruins your mashine.
You mean "don't use scanf improperly". Like every standard library
function (with the exception of gets()), scanf can be used correctly
and with complete safety. You are correct in condemning the OP's use
of the function; it is as (un)safe as gets(). A field-width specifier
would solve the problem nicely, however.
3. tell the compiler to serve all, really all possible warnings


For practical purposes, that's correct, although it is possible to go
overboard (it isn't difficult with lint-like programs)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #38
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:id********************************@4ax.com...
On Mon, 18 Oct 2004 21:03:14 GMT, in comp.lang.c , Keith Thompson
<ks***@mib.org> wrote:
It's true that you don't need the cast, but your explanation is a bit
off.


I prefer "oversimplified".... :-)
But I agree with your correction.

By the way sorry if my posts start appearing multiple times - my news
provider is having some sort of hairy fit and seems to be rejecting but at
the same time accepting some postings. Gah.


I suggest you get a 'backup' provider. My provider's servers
sometime get 'sick' too, in which case I fall back on
'individual.news.NET'. It takes them a few days to
activate an account after registration, but now it's
there when I need it. And there are many others out there.

-Mike
Nov 14 '05 #39
>yeah i can follow that now its kind of like
the old dos problem with far pointers where you end up working on a 16bit
and being able to address more than 64kb of data baecause of the segment
selector. Which used to be called far pointers but c compilers used to
"hide" this functionallity.

I was not aware any processors would have trapped on accessing the value
of an pointer would have cause this to happen.
The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.
I assume now the same can also happen with something like this.

int *p;
printf("%p\n");

on the same sorts of system.


Yes, but you didn't need the declaration of p to get undefined
behavior. Just leaving off the argument to printf() matching %p
is enough.

Gordon L. Burditt
Nov 14 '05 #40
go***********@burditt.org (Gordon Burditt) writes:
yeah i can follow that now its kind of like
the old dos problem with far pointers where you end up working on a 16bit
and being able to address more than 64kb of data baecause of the segment
selector. Which used to be called far pointers but c compilers used to
"hide" this functionallity.

I was not aware any processors would have trapped on accessing the value
of an pointer would have cause this to happen.


The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.


Does loading a null pointer into ES:SI or ES:ESI cause a trap?
I assume now the same can also happen with something like this.

int *p;
printf("%p\n");

on the same sorts of system.


Yes, but you didn't need the declaration of p to get undefined
behavior. Just leaving off the argument to printf() matching %p
is enough.


Yes, but that illustrates a different point.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #41
>go***********@burditt.org (Gordon Burditt) writes:
The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.

In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:Does loading a null pointer into ES:SI or ES:ESI cause a trap?


It could be arranged to do so, by making NULL's segment invalid.

If a compiler/system did set this up, so that in:

char *p, *q;
p = NULL;
q = p;

the assigment "q = p" trapped by loading p's NULL-value segment
into a segment register, that compiler/system would fail to conform.
The easiest way to fix this is to make sure that the "null segment"
(whatever segment number the compiler-writer chooses) is always
valid, if for some reason it is important to allow "q = p" to load
p's segment into a segment register.

In other words, simply loading a bad pointer into causes a trap, but it
should be OK to "load NULL", as long as you do not indirect through it:

p = NULL;
use(p); /* OK */
use2(*p); /* ERROR */

so a compiler must not trap on the call to use(), in case it
longjmp()s away. If it traps on the call to use2() (assuming this
call is actually attempted), that is fine. Since the hardware
traps on a load of the segment register with an invalid segment,
either NULL's segment has to be invalid, or the call to use()
has to not load the segment register (or both).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #42
>>>yeah i can follow that now its kind of like
the old dos problem with far pointers where you end up working on a 16bit
and being able to address more than 64kb of data baecause of the segment
selector. Which used to be called far pointers but c compilers used to
"hide" this functionallity.

I was not aware any processors would have trapped on accessing the value
of an pointer would have cause this to happen.


The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.


Does loading a null pointer into ES:SI or ES:ESI cause a trap?


That depends on what bit pattern you use for a null pointer. The
short answer is NO for an all-bits-zero null pointer.

I think some of the logic in handling selectors on the x86 architecture
was designed for C.

The all-bits-zero selector (actually, the two low-order bits of 16
are a don't care in this situation) generates a trap if you load
it into CS or SS. It doesn't cause a trap if you load it into DS,
ES, FS or GS. You *CANNOT* map that selector to anything. You
also can't dereference the pointer without a trap.

You can't load an all-bits-zero selector into CS since loading
CS:EIP is a branch instruction, and it's impossible to avoid
dereferencing it on the next instruction. The processor is rather
picky about keeping a valid stack pointer and it's difficult to
avoid dereferences into the stack segment if SS is NULL. I suppose
you could come up with a useful code sequence that loads SS with
NULL and manages not to dereference it, but the processor doesn't
allow it.

Gordon L. Burditt
Nov 14 '05 #43
Typo alert (low blood sugar? :-) ... was posting just post-gym):

In article <news:cl*********@news2.newsguy.com> I wrote:
... Since the hardware
traps on a load of the segment register with an invalid segment,
either NULL's segment has to be invalid, or the call to use()
has to not load the segment register (or both).


Of course, that should read "either NULL's segment has to be VALID"
(not "invalid").
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #44
>>> The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.
The easiest way to fix this is to make sure that the "null segment"
(whatever segment number the compiler-writer chooses) is always
valid, if for some reason it is important to allow "q = p" to load
p's segment into a segment register.

In other words, simply loading a bad pointer into causes a trap, but it
should be OK to "load NULL", as long as you do not indirect through it:

p = NULL;
use(p); /* OK */
use2(*p); /* ERROR */

so a compiler must not trap on the call to use(), in case it
longjmp()s away. If it traps on the call to use2() (assuming this
call is actually attempted), that is fine. Since the hardware
traps on a load of the segment register with an invalid segment,
either NULL's segment has to be invalid, or the call to use() validhas to not load the segment register (or both).


BUT, there's an odd halfway-in-between case for the all-bits-zero
selector (Intel x86 architecture): it's always a valid segment (so
you can load the pointer into a segment register without a trap),
but you can't dereference it. Just what you'd want for a null
pointer. And that particular selector ALWAYS acts like that: you
can't change it.

Gordon L. Burditt
Nov 14 '05 #45
Gordon Burditt wrote:
.... snip ...
BUT, there's an odd halfway-in-between case for the all-bits-zero
selector (Intel x86 architecture): it's always a valid segment (so
you can load the pointer into a segment register without a trap),
but you can't dereference it. Just what you'd want for a null
pointer. And that particular selector ALWAYS acts like that: you
can't change it.


Oh, you can dereference it, but you probably shouldn't. If you do
you are messing with the zero-divide interrupt vector, IIRC.

--
"I support the Red Sox and any team that beats the Yankees"
"Any baby snookums can be a Yankee fan, it takes real moral
fiber to be a Red Sox fan"
"I listened to Toronto come back from 3:0 in '42, I plan to
watch Boston come back from 3:0 in 04"
Nov 14 '05 #46
On 20 Oct 2004, Gordon Burditt wrote:
yeah i can follow that now its kind of like
the old dos problem with far pointers where you end up working on a 16bit
and being able to address more than 64kb of data baecause of the segment
selector. Which used to be called far pointers but c compilers used to
"hide" this functionallity.

I was not aware any processors would have trapped on accessing the value
of an pointer would have cause this to happen.


The Intel *86 architecture (in 16-bit or 32-bit protected mode) is
an excellent example of this. Loading a (so-called "far") pointer
containing a no-longer-valid segment into, say, ES:SI or ES:ESI
will cause a trap.
I assume now the same can also happen with something like this.

int *p;
printf("%p\n");

on the same sorts of system.


Yes, but you didn't need the declaration of p to get undefined
behavior. Just leaving off the argument to printf() matching %p
is enough.


Yeah please note the time on the posting

Date: Wed, 20 Oct 2004 00:43:43 +0100
From: James Stevenson <ja***@stev.org>

--
--------------------------
Mobile: +44 07779080838
http://www.stev.org
12:30pm up 19:28, 5 users, load average: 3.89, 3.88, 3.77

Nov 14 '05 #47
In article <cl*********@news2.newsguy.com>,
Chris Torek <no****@torek.net> wrote:
In other words, simply loading a bad pointer into causes a trap, but it
should be OK to "load NULL", as long as you do not indirect through it:

p = NULL;
use(p); /* OK */
use2(*p); /* ERROR */

so a compiler must not trap on the call to use(), in case it
longjmp()s away.


Isn't it enough for use() to involve user-visible side effects like
input or output?

Or would that lead us to a long and twisty thread arguing about what
constitutes a strictly conforming use of user-visible side effects,
rather than simply invalidating a trap on the call to use()?
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
But they're not strings. Not being strings doesn't stop them being useful.
After all, ints aren't strings, yet they are very useful indeed!
--Richard Heathfield in comp.lang.c
Nov 14 '05 #48
On Wed, 20 Oct 2004 00:18:24 GMT, in comp.lang.c , "Mike Wahler"
<mk******@mkwahler.net> wrote:
"Mark McIntyre" <ma**********@spamcop.net> wrote in message

By the way sorry if my posts start appearing multiple times - my news
provider is having some sort of hairy fit and seems to be rejecting but at
the same time accepting some postings. Gah.


I suggest you get a 'backup' provider.


I have one. Problem was that my normal provider was *silently*
rejecting-but-accepting posts, and didn't advise my newsclient till I tried
to end the session....
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #49
>> BUT, there's an odd halfway-in-between case for the all-bits-zero
selector (Intel x86 architecture): it's always a valid segment (so
you can load the pointer into a segment register without a trap),
but you can't dereference it. Just what you'd want for a null
pointer. And that particular selector ALWAYS acts like that: you
can't change it.


Oh, you can dereference it, but you probably shouldn't. If you do
you are messing with the zero-divide interrupt vector, IIRC.


No, you AREN'T messing with the zero-divide interrupt vector. The
global table doesn't have an entry 0 (even though where it would
logically go may overlap that vector). If you try to dereference a
NULL pointer (all-zero-bit selector), the processor won't look at
that entry, and even if you screw up the zero-divide vector to be
a valid table entry with associated memory, the dereference won't
work.

The all-bits zero selector (low-order two bits actually are don't-cares)
is a special case designed into the chip.

Gordon L. Burditt
Nov 14 '05 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: lasek | last post by:
Hi...i'm writing from Rome...and i don't know english very well so... Only simple question, which is the difference between those two parts of code. int *pInt=NULL; int iVar=10; pInt=&iVar;
5
by: lasek | last post by:
Hi all...now after a lot of experiments in c programming(two weeks..for precision), i've seen another strange instraction..and i post you the question... Like in the subject...why i must use nmap...
2
by: BLUE | last post by:
I want to store and retrieve datetime in ISO 8601 format: '2007-06-02T16:12:08.123-04:34' or '2007-06-02T16:12:08.123Z' When I insert a datetime with SQL Server Management Studio and then I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.