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

M

Mark McIntyre

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

Mark McIntyre

someone whose attribution James snipped said, talking of free.

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

CBFalconer

James Stevenson wrote: *** And again rudely removed attributes ***
.... snip ...

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:
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
 
K

Keith Thompson

Mike Wahler said:
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.)
 
O

Old Wolf

James Stevenson said:
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.
 
M

Mark McIntyre

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
 
B

bd

James said:
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. */
 
J

Jack Klein

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

lasek

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

pete

lasek said:
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>
 
R

Richard Bos

[ Please stop snipping all attributions - leave those which refer to
text that's still in the post. ]
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
 
K

Keith Thompson

Jack Klein said:
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.
 
O

Old Wolf

Jack Klein said:
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?
 
H

Herbert Rosenau

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

Mark McIntyre

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
 
M

Mark McIntyre

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

James Stevenson

[ Please stop snipping all attributions - leave those which refer to
text that's still in the post. ]
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
 
C

Christopher Benson-Manica

Herbert Rosenau said:
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.
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)
 
M

Mike Wahler

Mark McIntyre said:
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
 
G

Gordon Burditt

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
 

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

Similar Threads

Alternative to Malloc in C 0
Open letter to Ian Collins 32
malloc 40
C + Malloc 8
Breakthrough 25
Fibonacci 0
malloc and maximum size 56
STRING - Remove small letters from string 1

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top