By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,245 Members | 1,101 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,245 IT Pros & Developers. It's quick & easy.

Structure having pointers

P: n/a
Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;
}

Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?

Thanks in advance!!!

Jul 29 '07 #1
Share this Question
Share on Google+
38 Replies


P: n/a
Hi,
when you write b=a you copy the memory of the struct instance a in b.
In this way you copy the pointer p of a in b. Now a.p and b.p point to
the same memory.
To make a depth copy of the struct you have to write a function:

struct Sample* SampleCopy(struct Sample* src)
{
struct Sample* b=NULL;
b=(struct Sample*)malloc(sizeof(struct Sample));
b.i=src.i;
b.p=(char*)malloc(sizeof(char)*(strlen(src.p)+1));
memcpy(b.p,src.p);
return b;
}

int main()
{
Sample a;
a.p = (char*)malloc(10);
Sample *b;
b = SampleCopy(&a);

free(a.p);
free(a);
printf("%s",b->p); //should work!!
}

I think in this way you may solve your problem... if I've understood.
Probably I've committed some errors in the code.. but I've not a
reference now!

Bye
Gio
On 29 Lug, 12:20, sam_...@yahoo.co.in wrote:
Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;

}

Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?

Thanks in advance!!!


Jul 29 '07 #2

P: n/a
sa*****@yahoo.co.in wrote:
Hi,

I have the following Struct,

Struct Sample
The keyword is struct, not Struct. C is case sensitive.
{
int i;
char *p;
};

int main()
{
Sample a;
The declaration should be:

struct Sample a;
a.p = malloc(10);
Sample b;
As above.
b = a;
}

Now i think a shallow copy is done
Since a.i has an indeterminate value, the copy invokes undefined behaviour.
and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?
Deallocate the memory by calling free on either a.p or b.p, and set them
both to NULL.

Jul 29 '07 #3

P: n/a
AnticitizenOne wrote:

[top-post corrected]
On 29 Lug, 12:20, sam_...@yahoo.co.in wrote:
>Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;

}

Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?

Hi,
when you write b=a you copy the memory of the struct instance a in b.
In this way you copy the pointer p of a in b. Now a.p and b.p point to
the same memory.
To make a depth copy of the struct you have to write a function:

struct Sample* SampleCopy(struct Sample* src)
{
struct Sample* b=NULL;
b=(struct Sample*)malloc(sizeof(struct Sample));
The cast isn't recommended in C.
b.i=src.i;
b.p=(char*)malloc(sizeof(char)*(strlen(src.p)+1));
And sizeof(char) is always one in C.
memcpy(b.p,src.p);
return b;
}

int main()
{
Sample a;
It should be struct Sample a;
a.p = (char*)malloc(10);
Sample *b;
Mixed code and declarations are not allowed in C89 though they're allowed in
C99.
b = SampleCopy(&a);

free(a.p);
free(a);
printf("%s",b->p); //should work!!
return 0;
}
Jul 29 '07 #4

P: n/a

<sa*****@yahoo.co.inwrote in message
news:11**********************@i38g2000prf.googlegr oups.com...
Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;
}

Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?

Thanks in advance!!!
Do it like this

struct Sample *sample(int N)
{
struct Sample *answer;
answer = malloc(sizeof(struct Sample));
if(!answer)
goto error_exit;
answer.p = malloc(N);
if(!answer.p)
goto error_exit;
return answer;
error_exit:
killSample(answer);
return 0;
}

void killSample(struct Sample *s)
{
if(s)
{
free(s.p);
free(s);
}
}

struct Sample *Sample_clone(struct Sample *s)
{
struct Sample *answer;

answer = sample(s.N):
if(!answer)
return 0;
memcpy(answer.p, s.p, s.N);
return answer;
}

All we are doing is replacing member functions with fucntions which take a
struct Sample * as a parameter. For simplicity everything is kept in dynamic
memory - very rarely this will cause a performance problem and need to be
changed - but it simpifies the code management.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 29 '07 #5

P: n/a
sa*****@yahoo.co.in said:
Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;
}
In addition to other people's comments, I would point out that this code
is not legal in either C90 or C99. The absence of a function declarator
for malloc requires a diagnostic message under the rules of either
Standard, and the mixing of declarations with code requires a
diagnostic message under C90.

I suggest you increase your compiler's level of diagnostic checking
until it conforms with the Standard's requirements.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 29 '07 #6

P: n/a
On 29 Lug, 14:04, santosh <santosh....@gmail.comwrote:
AnticitizenOne wrote:

[top-post corrected]
On 29 Lug, 12:20, sam_...@yahoo.co.in wrote:
Hi,
I have the following Struct,
Struct Sample
{
int i;
char *p;
};
int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;
}
Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?
Hi,
when you write b=a you copy the memory of the struct instance a in b.
In this way you copy the pointer p of a in b. Now a.p and b.p point to
the same memory.
To make a depth copy of the struct you have to write a function:
struct Sample* SampleCopy(struct Sample* src)
{
struct Sample* b=NULL;
b=(struct Sample*)malloc(sizeof(struct Sample));

The cast isn't recommended in C.
b.i=src.i;
b.p=(char*)malloc(sizeof(char)*(strlen(src.p)+1));

And sizeof(char) is always one in C.
memcpy(b.p,src.p);
return b;
}
int main()
{
Sample a;

It should be struct Sample a;
a.p = (char*)malloc(10);
Sample *b;

Mixed code and declarations are not allowed in C89 though they're allowed in
C99.
b = SampleCopy(&a);
free(a.p);
free(a);
printf("%s",b->p); //should work!!

return 0;
}
Sorry for my errors... 90% of them are for distraction and cut'n
paste...
b=(struct Sample*)malloc(sizeof(struct Sample));

The cast isn't recommended in C.
This is really new for me o_O
I use the cast a lot... why in C is not recommended?

thanks!
bye
Gio

Jul 29 '07 #7

P: n/a
AnticitizenOne said:
On 29 Lug, 14:04, santosh <santosh....@gmail.comwrote:
>AnticitizenOne wrote:
<snip>
b=(struct Sample*)malloc(sizeof(struct Sample));

The cast isn't recommended in C.
This is really new for me o_O
I use the cast a lot...
Why?
why in C is not recommended?
Several reasons, but before we get into those reasons, let's find out
your reasons for using the cast.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 29 '07 #8

P: n/a
santosh <sa*********@gmail.comwrites:
sa*****@yahoo.co.in wrote:
>Hi,

I have the following Struct,

Struct Sample

The keyword is struct, not Struct. C is case sensitive.
> {
int i;
char *p;
};

int main()
{
Sample a;

The declaration should be:

struct Sample a;
> a.p = malloc(10);
Sample b;

As above.
> b = a;
}

Now i think a shallow copy is done

Since a.i has an indeterminate value, the copy invokes undefined
behaviour.
How?
>
> and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?

Deallocate the memory by calling free on either a.p or b.p, and set them
both to NULL.
--
Jul 29 '07 #9

P: n/a
On 29 Lug, 14:39, Richard Heathfield <r...@see.sig.invalidwrote:
AnticitizenOne said:
On 29 Lug, 14:04, santosh <santosh....@gmail.comwrote:
AnticitizenOne wrote:

<snip>
b=(struct Sample*)malloc(sizeof(struct Sample));
The cast isn't recommended in C.
This is really new for me o_O
I use the cast a lot...

Why?
why in C is not recommended?

Several reasons, but before we get into those reasons, let's find out
your reasons for using the cast.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
I use the cast as referenced in C-Language (Kerningan & Ritchie)

Jul 29 '07 #10

P: n/a
AnticitizenOne wrote:
On 29 Lug, 14:39, Richard Heathfield <r...@see.sig.invalidwrote:
>AnticitizenOne said:
On 29 Lug, 14:04, santosh <santosh....@gmail.comwrote:
AnticitizenOne wrote:

<snip>
b=(struct Sample*)malloc(sizeof(struct Sample));
>The cast isn't recommended in C.
This is really new for me o_O
I use the cast a lot...

Why?
why in C is not recommended?

Several reasons, but before we get into those reasons, let's find out
your reasons for using the cast.

I use the cast as referenced in C-Language (Kerningan & Ritchie)
That book was written before the first Standard for C was published. At that
point, there was no void * as a generic pointer type, but instead that
purpose was served by the char * type. Since then it's not necessary in C
to cast between a void * and another pointer type. Any pointer can be
converted to a void * and back again without any loss of information.

Infact casting the return value of malloc can prevent your compiler from
warning you when you fail to include stdlib.h, which declares malloc's
prototype. This can lead to possible undefined behaviour.

The only real reason for casting the return of malloc in C is if you're
forced to compile it under a C++ compiler or in a mixed C and C++
environment. That's pretty rare.

Jul 29 '07 #11

P: n/a
On 29 Lug, 14:53, santosh <santosh....@gmail.comwrote:
AnticitizenOne wrote:
On 29 Lug, 14:39, Richard Heathfield <r...@see.sig.invalidwrote:
AnticitizenOne said:
On 29 Lug, 14:04, santosh <santosh....@gmail.comwrote:
AnticitizenOne wrote:
<snip>
b=(struct Sample*)malloc(sizeof(struct Sample));
The cast isn't recommended in C.
This is really new for me o_O
I use the cast a lot...
Why?
why in C is not recommended?
Several reasons, but before we get into those reasons, let's find out
your reasons for using the cast.
I use the cast as referenced in C-Language (Kerningan & Ritchie)

That book was written before the first Standard for C was published. At that
point, there was no void * as a generic pointer type, but instead that
purpose was served by the char * type. Since then it's not necessary in C
to cast between a void * and another pointer type. Any pointer can be
converted to a void * and back again without any loss of information.

Infact casting the return value of malloc can prevent your compiler from
warning you when you fail to include stdlib.h, which declares malloc's
prototype. This can lead to possible undefined behaviour.

The only real reason for casting the return of malloc in C is if you're
forced to compile it under a C++ compiler or in a mixed C and C++
environment. That's pretty rare.
uh! Thanks! I've understood.

Jul 29 '07 #12

P: n/a
Richard wrote:
>
santosh <sa*********@gmail.comwrites:
sa*****@yahoo.co.in wrote:
Hi,

I have the following Struct,

Struct Sample
The keyword is struct, not Struct. C is case sensitive.
{
int i;
char *p;
};

int main()
{
Sample a;
The declaration should be:

struct Sample a;
a.p = malloc(10);
Sample b;
As above.
b = a;
}

Now i think a shallow copy is done
Since a.i has an indeterminate value, the copy invokes undefined
behaviour.

How?
Simply and obviously.

--
pete
Jul 29 '07 #13

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
<sa*****@yahoo.co.inwrote in message
news:11**********************@i38g2000prf.googlegr oups.com...
>Hi,

I have the following Struct,

Struct Sample
{
int i;
char *p;
};

int main()
{
Sample a;
a.p = malloc(10);
Sample b;
b = a;
}

Now i think a shallow copy is done and if i destry only on the object
there would be a dangling pointer.
How do i overcome this problem as C structures don't support
functions?
Do it like this

struct Sample *sample(int N)
{
struct Sample *answer;
answer = malloc(sizeof(struct Sample));
if(!answer)
goto error_exit;
answer.p = malloc(N);
if(!answer.p)
goto error_exit;
return answer;
error_exit:
killSample(answer);
return 0;
}

void killSample(struct Sample *s)
{
if(s)
{
free(s.p);
free(s);
}
}

struct Sample *Sample_clone(struct Sample *s)
{
struct Sample *answer;

answer = sample(s.N):
if(!answer)
return 0;
memcpy(answer.p, s.p, s.N);
return answer;
}
Depending on how you count them, you have about 8 errors and a rather
complex way of doing things. I would write:

struct Sample *sample_clone(struct Sample *sp)
{
struct Sample *answer = malloc(sizeof *answer);
if (answer && (answer->p = malloc(sp->i)))
memcpy(answer->p, sp->p, sp->i);
else {
free(answer);
answer = NULL;
}
return answer;
}

void sample_kill(struct Sample *sp)
{
if (sp) free(sp->p);
free(sp);
}

I know that many people don't like this style, but I think C works
that way. I am sure that it is not accidental that things like short
circuit &&, assignments in conditionals, and being able to free NULL all
work together to make compact, idiomatic code.

--
Ben.
Jul 29 '07 #14

P: n/a
pete <pf*****@mindspring.comwrites:
Richard wrote:
>>
santosh <sa*********@gmail.comwrites:
sa*****@yahoo.co.in wrote:

Hi,

I have the following Struct,

Struct Sample

The keyword is struct, not Struct. C is case sensitive.

{
int i;
char *p;
};

int main()
{
Sample a;

The declaration should be:

struct Sample a;

a.p = malloc(10);
Sample b;

As above.

b = a;
}

Now i think a shallow copy is done

Since a.i has an indeterminate value, the copy invokes undefined
behaviour.

How?

Simply and obviously.
I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
Jul 29 '07 #15

P: n/a
Richard wrote:
pete <pf*****@mindspring.comwrites:
>>>Since a.i has an indeterminate value, the copy invokes undefined
behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...
Jul 29 '07 #16

P: n/a
regis wrote:
Richard wrote:
>pete <pf*****@mindspring.comwrites:
>>>>Since a.i has an indeterminate value, the copy invokes undefined
behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...
But no integer is copied: a structure is copied, and a structure cannot have
a trap representation. This might have been different in previous
standards, but currently, you are allowed to copy even completely
uninitialised structures and unions.
Jul 29 '07 #17

P: n/a
Harald van D?k wrote:
regis wrote:
>Richard wrote:
>>pete <pf*****@mindspring.comwrites:
>>>>>Since a.i has an indeterminate value, the copy invokes undefined
>behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

But no integer is copied: a structure is copied, and a structure cannot
have a trap representation. This might have been different in previous
standards, but currently, you are allowed to copy even completely
uninitialised structures and unions.
Thanks for that correction. I'll keep that in mind.

Jul 29 '07 #18

P: n/a
regis <re**************@free.frwrites:
Richard wrote:
>pete <pf*****@mindspring.comwrites:
>>>>Since a.i has an indeterminate value, the copy invokes undefined
behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...
Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.
Jul 29 '07 #19

P: n/a
Richard wrote:
regis <re**************@free.frwrites:
>Richard wrote:
>>pete <pf*****@mindspring.comwrites:
>>>>>Since a.i has an indeterminate value, the copy invokes undefined
>behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.
As Harald has pointed out, I'm wrong on this.

Jul 29 '07 #20

P: n/a
santosh wrote:
Harald van D?k wrote:
>regis wrote:
>>Richard wrote:
pete <pf*****@mindspring.comwrites:
>>Since a.i has an indeterminate value, the copy invokes undefined
>>behaviour.
>How?
Simply and obviously.
I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...
>But no integer is copied: a structure is copied, and a structure cannot
have a trap representation. This might have been different in previous
standards, but currently, you are allowed to copy even completely
uninitialised structures and unions.

Thanks for that correction. I'll keep that in mind.
That was my line...

Jul 29 '07 #21

P: n/a
Harald van Dijk <tr*****@gmail.comwrites:
regis wrote:
>Richard wrote:
>>pete <pf*****@mindspring.comwrites:
>>>>>Since a.i has an indeterminate value, the copy invokes undefined
>behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

But no integer is copied: a structure is copied, and a structure cannot have
a trap representation. This might have been different in previous
standards, but currently, you are allowed to copy even completely
uninitialised structures and unions.
This makes more sense to me. The structure "copy/assign" would normally
just be a memcpy or similar I would have thought.
Jul 29 '07 #22

P: n/a
Richard wrote:
regis <re**************@free.frwrites:
>Richard wrote:
>>pete <pf*****@mindspring.comwrites:
>Since a.i has an indeterminate value, the copy invokes undefined
>behaviour.
How?
Simply and obviously.
I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.
Thinking of it, this is just how changing the attributes
of X11 window work: we partially fill a structure
with the values we want to change and we set a bit-mask
indicating which values are defined in the structure...
Jul 29 '07 #23

P: n/a
regis wrote:
Richard wrote:
>regis <re**************@free.frwrites:
>>Richard wrote:
pete <pf*****@mindspring.comwrites:
>>Since a.i has an indeterminate value, the copy invokes undefined
>>behaviour.
>How?
Simply and obviously.
I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.

Thinking of it, this is just how changing the attributes
of X11 window work: we partially fill a structure
with the values we want to change and we set a bit-mask
indicating which values are defined in the structure...
time to put some distance between me and from keyboard,
the structure is not passed by value to the function and
hence a copy the partially filled struct is not done...
Jul 29 '07 #24

P: n/a
regis <re**************@free.frwrites:
Richard wrote:
>regis <re**************@free.frwrites:
>>Richard wrote:
pete <pf*****@mindspring.comwrites:
>>Since a.i has an indeterminate value, the copy invokes undefined
>>behaviour.
>How?
Simply and obviously.
I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.

Thinking of it, this is just how changing the attributes
of X11 window work: we partially fill a structure
with the values we want to change and we set a bit-mask
indicating which values are defined in the structure...
But for totally different reasons I suspect. At a guess this is so that
you only send changed/set parameters in the X protocol - reduces
bandwidth requirements. Nothing to do with "undefined behaviour invoked
by copying an uninitialized integer".

Besides, I seriously doubt that the integer field of a newly created
structure can ever hold an "illegal" system value in the real world.
Jul 29 '07 #25

P: n/a
santosh <sa*********@gmail.comwrites:
Richard wrote:
>regis <re**************@free.frwrites:
>>Richard wrote:
pete <pf*****@mindspring.comwrites:

>>Since a.i has an indeterminate value, the copy invokes undefined
>>behaviour.
>How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?

suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

Is this really defined as Undefined Behaviour?

I have seen TONS of SW where structures only set certain elements and
then are shallow copied for inclusion into linked lists etc.

As Harald has pointed out, I'm wrong on this.
I posted that before Harald replied. Pete was too. Thanks for
acknowledging.
Jul 29 '07 #26

P: n/a
In article <6l************@gmail.com>, Richard <rg****@gmail.comwrote:
>regis <re**************@free.frwrites:
....
>Besides, I seriously doubt that the integer field of a newly created
structure can ever hold an "illegal" system value in the real world.
The real world is (by explicit decree - no, I am not making this up)
irrelevant here.

Jul 29 '07 #27

P: n/a

"Richard" <rg****@gmail.comwrote in message
news:6l************@gmail.com...
>
Besides, I seriously doubt that the integer field of a newly created
structure can ever hold an "illegal" system value in the real world.
It's a potential enhancement. All unitialised objects are set to trap. If
the value is used then the program aborts.
I don't know of a single system that actually does this, but it would be
better, since you'd catch bugs earlier. The downside is that a struct
assignment would need care, because logically you might not need certain
fields, but the compiler can't be expected to know that.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 29 '07 #28

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
"Richard" <rg****@gmail.comwrote in message
news:6l************@gmail.com...
>>
Besides, I seriously doubt that the integer field of a newly created
structure can ever hold an "illegal" system value in the real world.
It's a potential enhancement. All unitialised objects are set to
trap. If the value is used then the program aborts.
I don't know of a single system that actually does this, but it would
be better, since you'd catch bugs earlier. The downside is that a
struct assignment would need care, because logically you might not
need certain fields, but the compiler can't be expected to know that.
It's a terrible idea. I don't necessarily WANT to initialise all
variables in certain structures. A control flag dictates which fields
are in "use" and don't all necessarily lend themselves to being in a Union.

If you want that level of control use something like ADA. C is C for a
reason - powerful and efficient and puts things in the programmers hands.
Jul 29 '07 #29

P: n/a
In article <ox************@gmail.com>, Richard <rg****@gmail.comwrote:
>"Malcolm McLean" <re*******@btinternet.comwrites:
>"Richard" <rg****@gmail.comwrote in message
news:6l************@gmail.com...
>>>
Besides, I seriously doubt that the integer field of a newly created
structure can ever hold an "illegal" system value in the real world.
It's a potential enhancement. All unitialised objects are set to
trap. If the value is used then the program aborts.
I don't know of a single system that actually does this, but it would
be better, since you'd catch bugs earlier. The downside is that a
struct assignment would need care, because logically you might not
need certain fields, but the compiler can't be expected to know that.

It's a terrible idea. I don't necessarily WANT to initialise all
variables in certain structures. A control flag dictates which fields
are in "use" and don't all necessarily lend themselves to being in a Union.
It's a really terrible idea because it would break tons of existing, working,
code.

Jul 29 '07 #30

P: n/a
Harald van =?UTF-8?B?RMSzaw==?= wrote:
>
regis wrote:
Richard wrote:
pete <pf*****@mindspring.comwrites:
>>>Since a.i has an indeterminate value, the copy invokes undefined
behaviour.
How?
Simply and obviously.

I think I have my dumb head on today Aunt Sally.

Really, how does the copy invoke undefined behaviour?

An undefined value is copied, but how does the invoke undefined
behaviour at the point of the copy?
suppose that moving an integer from memory to memory
requires to load it first into a register.
Now, suppose the undefined bit pattern of this integer
is a trap representation that triggers
an exception once the value is loaded in the register...

But no integer is copied: a structure is copied,
and a structure cannot have
a trap representation. This might have been different in previous
standards, but currently, you are allowed to copy even completely
uninitialised structures and unions.
The C90 standard doesn't have the word "trap" in it,
but it does say this about indeterminate objects:

3.16 undefined behavior:
Behavior, upon use of a nonportable or erroneous program
construct, of erroneous data,
or of indeterminately valued objects,
for which this International Standard imposes no requirements.

Where in the C99 standard does it say no traps for structs?

All that I can find about traps and structs, applies to padding.

--
pete
Jul 29 '07 #31

P: n/a
santosh <sa*********@gmail.comwrites:
AnticitizenOne wrote:
>On 29 Lug, 14:39, Richard Heathfield <r...@see.sig.invalidwrote:
>>AnticitizenOne said:
[...]
>why in C is not recommended?

Several reasons, but before we get into those reasons, let's find out
your reasons for using the cast.

I use the cast as referenced in C-Language (Kerningan & Ritchie)

That book was written before the first Standard for C was published. At that
point, there was no void * as a generic pointer type, but instead that
purpose was served by the char * type. Since then it's not necessary in C
to cast between a void * and another pointer type. Any pointer can be
converted to a void * and back again without any loss of information.
I suspect the OP is using the second edition of Kernighan & Ritchie,
not K&R1. K&R2 was published shortly before the first C standard, but
describes essentially the same language as the C89 standard does --
including void*. As I recall, the examples in K&R2 do cast the result
of malloc, but the errata list at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.htmlsays:

The remark about casting the return value of malloc ("the proper
method is to declare ... then explicitly coerce") needs to be
rewritten. The example is correct and works, but the advice is
debatable in the context of the 1988-1989 ANSI/ISO standards. It's
not necessary (given that coercion of void * to ALMOSTANYTYPE * is
automatic), and possibly harmful if malloc, or a proxy for it,
fails to be declared as returning void *. The explicit cast can
cover up an unintended error. On the other hand, pre-ANSI, the
cast was necessary, and it is in C++ also.

If the OP really is using the first edition, he should get a copy of
the second edition; K&R1 is historically interesting, and it's still a
good book, but K&R2 is much more up to date.

See also questions 7.6, 7.7, 7.7b, and 7.7c in the comp.lang.c FAQ,
<http://www.c-faq.com/>.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 29 '07 #32

P: n/a
santosh <sa*********@gmail.comwrites:
sa*****@yahoo.co.in wrote:
>>
I have the following Struct,

Struct Sample

The keyword is struct, not Struct. C is case sensitive.
> {
int i;
char *p;
};

int main()
{
Sample a;

The declaration should be:

struct Sample a;
> a.p = malloc(10);
Sample b;

As above.
> b = a;
}

Now i think a shallow copy is done

Since a.i has an indeterminate value, the copy invokes undefined behaviour.
[...]

This is actually ambiguous in both C90 and C99. n1124 (which
incorporates C99 plus Technical Corrigenda 1 and 2) adds the following
wording in 6.2.6.1p6:

The value of a structure or union object is never a trap
representation, even though the value of a member of the structure
or union object may be a trap representation.

This was probably the intent previously, but it hadn't been stated
explicitly. Prior to n1124, it could be argued that the copy does
invoke UB. But I doubt that any real-world implementation does
anything other than just copying the representation using the
equivalent of memcpy(). Even an implementation that copies the
individual members one by one would be unlikely to cause problems.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 29 '07 #33

P: n/a
pete <pf*****@mindspring.comwrites:
[...]
Where in the C99 standard does it say no traps for structs?
It doesn't, but n1124 does. See my response elsethread.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 29 '07 #34

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
>>
struct Sample *sample_clone(struct Sample *sp)
{
struct Sample *answer = malloc(sizeof *answer);
if (answer && (answer->p = malloc(sp->i)))
memcpy(answer->p, sp->p, sp->i);
else {
free(answer);
answer = NULL;
}
return answer;
}
This approach is a blind alley. As you add members to logic to free
and abort becomes more and more complicated.
That arguments sounds like "it is going to get messy do lets start
messy". I'd prefer to solve today's problem and re-organise[1] *if*
required tomorrow -- the design version of avoiding premature
optimisation. However...
It is a lot better to
have a "clean up and return" section that is quite clearly not part of
normal execution.
In fact, that is pretty much what I have. It is the else. I think the
key thing is to ensure that all pointers are either NULL or malloc'ed
at the key times. calloc is not required to return storage
initialised to something that compares == to a null pointer constant,
so a bit more work is needed when the space has more than one pointer,
but it scales to more than one just fine:

struct big_sample *bsp = malloc(sizeof *bsp);
if (bsp) {
*bsp = (struct big_sample){0};
if ((bsp->ptr1 = malloc(src->sz1)) &&
(bsp->ptr2 = malloc(src->sz2)) &&
(bsp->ptr3 = malloc(src->sz3)) &&
(bsp->ptr4 = malloc(src->sz4))) {
/* all good to go now */
memcpy(bsp->ptr1, src->ptr1, src->sz1);
memcpy(bsp->ptr2, src->ptr2, src->sz2);
memcpy(bsp->ptr3, src->ptr3, src->sz3);
memcpy(bsp->ptr4, src->ptr4, src->sz4);
}
else {
free(bsp->ptr1);
free(bsp->ptr2);
free(bsp->ptr3);
free(bsp->ptr4);
free(bsp);
bsp = NULL;
}
}
return bsp;

so you get a bump from one if to two when you go from the common case
of one dependent thing to more than one, but it scales just fine.
Obviously, with this much regularity one would be using an array -- I
just kept the pattern simple so you could see how it scales. In a
real messy case, all the mallocs, sizes and memcpys would be different
and quirky.
>void sample_kill(struct Sample *sp)
{
if (sp) free(sp->p);
free(sp);
}
<snip>
The problem isthat for such a simple structure you are right. Add
another array and you've got to have a curly brace anyway. Get into
the habit of

void killme(MYSTRUCT *ptr)
{
if(ptr)
{
}
}
It is a matter of taste to some extent. If that were the "house
style" I'd use it, but I prefer minimal braces myself. I can't see:

if (sp)
free(sp->p1);
free(sp->p2);
free(sp);

(which is how the error would look) without a big alarm going off --
I'm getting a funny feeling just letting it sit there on the screen
now. For me, C's { }s are HUGE -- maybe from learning LISP so long
ago.

--
Ben.
Jul 30 '07 #35

P: n/a
Ben Bacarisse <be********@bsb.me.ukwrites:
I'd prefer to solve today's problem and re-organise[1] *if*
required tomorrow -- the design version of avoiding premature
optimisation.
I forgot my footnote:
[1] I am not keen on "refactor" for programs. It's just a linguistic
thing, the idea is fine.

--
Ben.
Jul 30 '07 #36

P: n/a

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
"Malcolm McLean" <re*******@btinternet.comwrites:
>"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
>>>
struct Sample *sample_clone(struct Sample *sp)
{
struct Sample *answer = malloc(sizeof *answer);
if (answer && (answer->p = malloc(sp->i)))
memcpy(answer->p, sp->p, sp->i);
else {
free(answer);
answer = NULL;
}
return answer;
}
This approach is a blind alley. As you add members to logic to free
and abort becomes more and more complicated.

That arguments sounds like "it is going to get messy do lets start
messy". I'd prefer to solve today's problem and re-organise[1] *if*
required tomorrow -- the design version of avoiding premature
optimisation. However...
>It is a lot better to
have a "clean up and return" section that is quite clearly not part of
normal execution.

In fact, that is pretty much what I have. It is the else. I think the
key thing is to ensure that all pointers are either NULL or malloc'ed
at the key times. calloc is not required to return storage
initialised to something that compares == to a null pointer constant,
so a bit more work is needed when the space has more than one pointer,
but it scales to more than one just fine:

struct big_sample *bsp = malloc(sizeof *bsp);
if (bsp) {
*bsp = (struct big_sample){0};
if ((bsp->ptr1 = malloc(src->sz1)) &&
(bsp->ptr2 = malloc(src->sz2)) &&
(bsp->ptr3 = malloc(src->sz3)) &&
(bsp->ptr4 = malloc(src->sz4))) {
/* all good to go now */
memcpy(bsp->ptr1, src->ptr1, src->sz1);
memcpy(bsp->ptr2, src->ptr2, src->sz2);
memcpy(bsp->ptr3, src->ptr3, src->sz3);
memcpy(bsp->ptr4, src->ptr4, src->sz4);
}
else {
free(bsp->ptr1);
free(bsp->ptr2);
free(bsp->ptr3);
free(bsp->ptr4);
free(bsp);
bsp = NULL;
}
}
return bsp;

so you get a bump from one if to two when you go from the common case
of one dependent thing to more than one, but it scales just fine.
Obviously, with this much regularity one would be using an array -- I
just kept the pattern simple so you could see how it scales. In a
real messy case, all the mallocs, sizes and memcpys would be different
and quirky.
>>void sample_kill(struct Sample *sp)
{
if (sp) free(sp->p);
free(sp);
}
<snip>
>The problem isthat for such a simple structure you are right. Add
another array and you've got to have a curly brace anyway. Get into
the habit of

void killme(MYSTRUCT *ptr)
{
if(ptr)
{
}
}

It is a matter of taste to some extent. If that were the "house
style" I'd use it, but I prefer minimal braces myself. I can't see:

if (sp)
free(sp->p1);
free(sp->p2);
free(sp);

(which is how the error would look) without a big alarm going off --
I'm getting a funny feeling just letting it sit there on the screen
now. For me, C's { }s are HUGE -- maybe from learning LISP so long
ago.
Your code looks like Lisp.
I'm sure it's possible to write an entire program in one if() statement,
with & and || providing the flow control, and recursuive calls to give
generality.
But it isn't C.
Your code seems to be desperate attempt to avoid a goto. Why? Just because
some person once published a paper?

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 30 '07 #37

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
>"Malcolm McLean" <re*******@btinternet.comwrites:
<snip>
>>It is a lot better to
have a "clean up and return" section that is quite clearly not part of
normal execution.

In fact, that is pretty much what I have. It is the else. I think the
key thing is to ensure that all pointers are either NULL or malloc'ed
at the key times. calloc is not required to return storage
initialised to something that compares == to a null pointer constant,
so a bit more work is needed when the space has more than one pointer,
but it scales to more than one just fine:

struct big_sample *bsp = malloc(sizeof *bsp);
if (bsp) {
*bsp = (struct big_sample){0};
if ((bsp->ptr1 = malloc(src->sz1)) &&
(bsp->ptr2 = malloc(src->sz2)) &&
(bsp->ptr3 = malloc(src->sz3)) &&
(bsp->ptr4 = malloc(src->sz4))) {
/* all good to go now */
memcpy(bsp->ptr1, src->ptr1, src->sz1);
memcpy(bsp->ptr2, src->ptr2, src->sz2);
memcpy(bsp->ptr3, src->ptr3, src->sz3);
memcpy(bsp->ptr4, src->ptr4, src->sz4);
}
else {
free(bsp->ptr1);
free(bsp->ptr2);
free(bsp->ptr3);
free(bsp->ptr4);
free(bsp);
bsp = NULL;
}
}
return bsp;

so you get a bump from one if to two when you go from the common case
of one dependent thing to more than one, but it scales just fine.
Obviously, with this much regularity one would be using an array
<snip>
Your code looks like Lisp.
You need to look a some LISP again! It does not even violate your
rather arbitrary "no more than three levels of brackets" rule that you
posted a while ago.
I'm sure it's possible to write an entire program in one if()
statement, with & and || providing the flow control, and recursuive
calls to give generality.
But it isn't C.
You do like to fight both sides of the debate! I don't know if what
you suggest is possible, but since I did not do it, I don't see the
value in bringing up such an absurd idea.
Your code seems to be desperate attempt to avoid a goto. Why? Just
because some person once published a paper?
No. I want the conditions under which code is executed to be clear
and self-evident. It is safe to do the object copy if (and only if)
all the storage has been allocated; and that should be stated as
clearly as possible. I think an 'if' does that. There are lots of
ways of calculating the expression used in the 'if'. Local house
style rules might require:
bsp->ptr1 = malloc(src->sz1);
bsp->ptr2 = malloc(src->sz2);
bsp->ptr3 = malloc(src->sz3);
bsp->ptr4 = malloc(src->sz4);
if (bsp->ptr1 && bsp->ptr2 && bsp->ptr3 && bsp->ptr4) {
...
}

or even:

int n_errors = 0;
if (bsp->ptr1 = malloc(src->sz1)) == NULL)
n_errors += 1;
...
if (n_errors == 0) {
...
}

I just put the code in to the condition explicitly -- the pattern is
the same.

Please note, I was never claiming good style -- that is a very complex
topic involving lots of variables, many of them social rather than
technical. I was refuting the bold statement that my approach was "a
blind alley"[1].

[1] I would say "dead end". Blind alleys can be fun to follow and
often lead to wide, appealing, vistas.

--
Ben.
Jul 31 '07 #38

P: n/a
Ben Bacarisse wrote:
[1] I would say "dead end". Blind alleys can be fun to follow and
often lead to wide, appealing, vistas.
(fx:OT) A blind alley /is/ a dead end. If you can get through it
to somewhere else, it isn't blind.

--
Squinting Hedgehog
"Our future looks secure, but it's all out of our hands"
- Magenta, /Man and Machine/

Jul 31 '07 #39

This discussion thread is closed

Replies have been disabled for this discussion.