473,785 Members | 2,553 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

=operator for structs

Hi,

I was wondering how the =operator works for
struct.

When I for example define a struct as follows:

struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.

Does this mean that structs can be assigned by '=' without any
problems even if they contain (pointer to) nested structs as
elements?

Thank you.
Chris
Mar 18 '06 #1
8 3024
Christian Christmann wrote:
Hi,

I was wondering how the =operator works for
struct.
It does a shallow copy.
When I for example define a struct as follows:

struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };
Note that "Hallo" is a string literal. Your p1->c will point to a
string, but
modifying that string invokes undefined behaviour.
and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.
This is an example of undefined behaviour in action.
Does this mean that structs can be assigned by '=' without any
problems
Generally yes. There isn't a problem with the assignment, there
is a problem withour subsequent use of the struct copy.
even if they contain (pointer to) nested structs as
elements?


Like I say, assignment only does a shallow copy.

--
Peter

Mar 18 '06 #2
Christian Christmann wrote:
Hi,

I was wondering how the =operator works for
struct.

When I for example define a struct as follows:

struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.
What do mean by "modificati on to p1.c"?

If you did something like this:

p1.c[0] = 'q';

Then you did a very bad thing, that's undefined behavior.
If you meant this:

p1.c = "a different string";
Then there's no problem.

Does this mean that structs can be assigned by '=' without any
problems even if they contain (pointer to) nested structs as
elements?


Unlikely. The pointers are copied exactly, each struct initially points
to the same item (assuming the pointers were set to a valid object's
address). However, you'll have to detail your problem more thoroughly.
You use terminology very loosely. Examples would help.

Brian
Mar 18 '06 #3
Christian Christmann <pl*****@yahoo. de> writes:
I was wondering how the =operator works for
struct.
By copying the values of all the members. It can either copy them one
at a time or, more likely, by doing the equivalent of a memcpy() on
the entire structure.
When I for example define a struct as follows:

struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.

Does this mean that structs can be assigned by '=' without any
problems even if they contain (pointer to) nested structs as
elements?


No, it doesn't. If a structure contains pointers, copying it by
assignment to another structure object just copies the pointers; both
pointers will point to the same external object. To use the jargon,
struct assignment does a "shallow copy", not a "deep copy".

p1.c, a pointer, is part of the structure, and is copied by the
assignment. The string that p1.c points to is not part of the
structure, and is not copied by the assignment.

Given the code above, you can modify p2.c without affecting p1 (just
as you can modify p2.a without affecting p1), but you can't modify
what p2.c points to without affecting p1 (or rather, affecting what
p1.c points to).

And in this case, since p1.c and p2.c both point to a string literal,
you can't legally modify it at all (attempting to do so invokes
undefined behavior).

Here's a program that illustrates what happens. Note that I've
initialized p1.c to point to a (non-const) array object rather than to
a string literal, so modifying the string is allowed.

=============== =============== ==
#include <stdio.h>
int main(void)
{
char hello[] = "hello";

struct point {
int a;
char *c;
};

struct point p1 = { 10, hello };
struct point p2;
p2 = p1;

printf("p1 = { %d, %p --> \"%s\" }\n", p1.a, (void*)p1.c, p1.c);
printf("p2 = { %d, %p --> \"%s\" }\n", p2.a, (void*)p2.c, p2.c);

printf("Modifyi ng p2.c[0]\n");
p2.c[0] = 'J';

printf("p1 = { %d, %p --> \"%s\" }\n", p1.a, (void*)p1.c, p1.c);
printf("p2 = { %d, %p --> \"%s\" }\n", p2.a, (void*)p2.c, p2.c);

printf("Modifyi ng p2.c\n");
p2.c = "Good-bye";

printf("p1 = { %d, %p --> \"%s\" }\n", p1.a, (void*)p1.c, p1.c);
printf("p2 = { %d, %p --> \"%s\" }\n", p2.a, (void*)p2.c, p2.c);

return 0;
}
=============== =============== ==

The output is:

p1 = { 10, 0x22eeb0 --> "hello" }
p2 = { 10, 0x22eeb0 --> "hello" }
Modifying p2.c[0]
p1 = { 10, 0x22eeb0 --> "Jello" }
p2 = { 10, 0x22eeb0 --> "Jello" }
Modifying p2.c
p1 = { 10, 0x22eeb0 --> "Jello" }
p2 = { 10, 0x40205d --> "Good-bye" }

Keep in mind that the printf with a "%p" format prints its argument (a
pointer), while printf with a "%s" format prints what its argument
points to (a string).

--
Keith Thompson (The_Other_Keit h) 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.
Mar 18 '06 #4
Christian Christmann wrote:
struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;
The previous line is equivalent to:
p2.a = p1.a; /* copy integer value */
p2.c = p1.c; /* copy pointer value */
it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.
p1.c and p2.c were always independent objects. A modification to p1.c
can never affect p2.c! Each of them holds a pointer value, and either
pointer value can be modified at any time.

However, no independent string is generated. Both p1.c and p2.c point to
the same string literal. The string literal, as always, is not
modifyable. If, however, it were a modifyable object, then you could see
that modifying it would result in the modifications being visible from
both p1.c and p2.c.
Does this mean that structs can be assigned by '=' without any
problems even if they contain (pointer to) nested structs as
elements?


If they contain nested structs as elements, then the nested structs will
be copied correctly by the '=' operator.

If they contain _pointers to_ nested structs as elements, then only the
pointer values will be copied. You will then have two pointers that
point to the same object. Modifying the underlying object will affect
access through either pointer.

--
Simon.
Mar 18 '06 #5
On 17 Mar 2006 16:20:12 -0800, "Peter Nilsson" <ai***@acay.com .au>
wrote:
Christian Christmann wrote:
Hi,

I was wondering how the =operator works for
struct.
It does a shallow copy.
When I for example define a struct as follows:

struct point {
int a;
char *c;
};

and create the first struct

struct point p1 = { 10, "Hallo" };


Note that "Hallo" is a string literal. Your p1->c will point to a
string, but
modifying that string invokes undefined behaviour.
and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

it seams that all elements are copied properly, i.e.
a new variable is created for 'a' but also, what is more interesting,
an independent string char* 'c' is generated since a
modification to p1.c does not affect p2.c.


This is an example of undefined behaviour in action.


No it isn't. It is perfectly legal to modify p1.c. What would invoke
undefined behavior would be modifying what p1.c points to while it
still points to a string literal.
Does this mean that structs can be assigned by '=' without any
problems
Generally yes. There isn't a problem with the assignment, there
is a problem withour subsequent use of the struct copy.


What problem are you referring to?
even if they contain (pointer to) nested structs as
elements?


Like I say, assignment only does a shallow copy.

Remove del for email
Mar 18 '06 #6
On Sat, 18 Mar 2006 00:24:29 +0000, Default User wrote:


struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;


What do mean by "modificati on to p1.c"?

If you did something like this:

p1.c[0] = 'q';

Then you did a very bad thing, that's undefined behavior.


Than k you for all yout helpful answers.
Why do I get an undefined behavior when modifying the string
p1.c points to? Isn't "Hello" a char array somewhere in the
memory that is referenced by p1.c and thus modification to single
char elements like p1.c[0] should be allowed?

Mar 21 '06 #7
Christian Christmann <pl*****@yahoo. de> wrote:
On Sat, 18 Mar 2006 00:24:29 +0000, Default User wrote:
struct point p1 = { 10, "Hallo" };
What do mean by "modificati on to p1.c"?

If you did something like this:

p1.c[0] = 'q';

Then you did a very bad thing, that's undefined behavior.


Than k you for all yout helpful answers.
Why do I get an undefined behavior when modifying the string
p1.c points to? Isn't "Hello" a char array somewhere in the
memory that is referenced by p1.c and thus modification to single
char elements like p1.c[0] should be allowed?


No. pl.c is a pointer to char; whether writing through this pointer
invokes UB depends on what it points at. In this case, it points at
"Hallo", which is a string literal; and string literals are translated
into arrays of char in memory _which may be in unwritable memory_. For
example, an embedded system long on ROM and short on RAM could put all
literal strings in ROM.

Richard
Mar 21 '06 #8
Christian Christmann wrote:
On Sat, 18 Mar 2006 00:24:29 +0000, Default User wrote:

struct point p1 = { 10, "Hallo" };

and then create another struct and assign it struct p1

struct point p2;
p2 = p1;

What do mean by "modificati on to p1.c"?

If you did something like this:

p1.c[0] = 'q';

Then you did a very bad thing, that's undefined behavior.


Than k you for all yout helpful answers.
Why do I get an undefined behavior when modifying the string
p1.c points to? Isn't "Hello" a char array somewhere in the
memory that is referenced by p1.c and thus modification to single
char elements like p1.c[0] should be allowed?


I'm assuming the definition of the struct was something line:
struct point {
int i;
char *p;
}

So, in other words, p1.c is a pointer to a string literal.

You are correct that "Hello" will be an array in memory somewhere, and
it will obviously have a /0 after it. However, the standard explicitly
states that you are not allowed to modify string literals, so modifying
it is undefined behaviour.

The reason the C language has this restriction is to allow the compiler
to put the string literal in read only memory (e.g. keep it in ROM on an
embedded system, or just in a page marked as read only on a hosted
system) and/or combine string literals, including combining the strings
"Let me say Hello", "Hello" and "lo".

So, depending on what the compiler does, some possible results would be
modifying all string literals that end in "Hello", causing the OS to
raise some form of access violation signal or error, causing an attempt
to write to memory that is physically read only (probably resulting in
nothing happening) or anything else.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 21 '06 #9

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

Similar topics

6
1899
by: Rick | last post by:
Hi again, I once saw that it was possible to define operators in C++ or something so I was thinking, is it possible to store and use operators in C? For example, first I read out a formula char by char. At some point I detect a operator char ( + / - * ^ mod etc. ). After parsing the formula I want to use it as quick as possible. So instead of reading that string again and again I'd like to store all the functions/values and operators in...
14
4694
by: indigodfw | last post by:
Greetings from India I would like to know the rationale on allowing structs to be assigned (using = operator) and not allowing equality operator ( == operator) on them. The compiler when it assigns using = is aware of holes etc and the same compiler then should be able to generate code to compare the individual struct fields.
9
2859
by: Steve Sargent | last post by:
Hi: I'm trying to debug the following code, and it keeps looping on the if statement: public static bool operator == (OnlineMemberNode first, OnlineMemberNode second) { if(first == null) {
1
1739
by: Andrew Larder | last post by:
Hi, I'm trying to write a high performance numerical app in C#, and would like to use operator overloading, but currently things are running a bit slower than non op-overloaded code. If I overload operators on a struct, lets for example say a Vector3 (3D vector), does this mean when I write: Vector3 a = new Vector(1,2,3);
12
1887
by: ozbear | last post by:
If one were writing a C interpreter, is there anything in the standard standard that requires the sizeof operator to yield the same value for two different variables of the same type? Let's assume that the interpreter does conform to the range values for, say, type int, but allocates storage for the variables based on their value. So, for two variables foo and bar int foo = 0; /* interpreter allocates two bytes */ int bar =...
9
1625
by: Lonnie Princehouse | last post by:
There doesn't seem to be any way to customize the behavior of "is" as can be done for other operators... why not?
12
2211
by: cody | last post by:
Why can I overload operator== and operator!= separately having different implementations and additionally I can override equals() also having a different implementation. Why not forbid overloading of == and != but instead translate each call of objA==objB automatically in System.Object.Equals(objA, objB). This would remove inconsistencies like myString1==myString2
11
3560
by: fungus | last post by:
I have some classes which have a "writeTo()" function but no operator<<. I want to fix it so that they all have an operator<< (for consistency). Can I do something like this: template <class T> DataDest& operator<<(DataDest& d, const T& t) { t.writeTo(d);
38
1394
by: MBSoftware | last post by:
Someone can explain me the meanings of the ? operator applied to declarations like that i found... private Point? startPoint; if i delete the ? the compiler gives me some errors but i don't understand what's the use of ? in that declaration position... help me please
0
9645
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9480
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10324
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10090
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8971
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7499
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4050
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2879
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.