473,847 Members | 1,439 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Copying objects and arrays

Ok, I'm quite a newbie, so this question may appear silly. I'm using
g++ 3.3.x.
I had been taught that an array isn't a lot different from a pointer
(in fact you can use the pointer arithmetics to "browse" it). So I
expected that when I run this program, I get both c1.A and c2.A
pointing to the same address, and changing c1.A means that also c2.A
changes too.

----- BEGIN example CODE -----------

#include <iostream>
using std::cout;
using std::endl;

class C {
private :
int A[3];

public:
C() { for( int i=0; i<3; i++ ) A[i] = 0; };
void alter() { A[1]++; };
void printA() const;
};

void
C::printA() const
{
for( int i=0; i<3; i++ )
cout << "A[" << i
<< "] is " << A[i]
<< endl;
}

int
main( )
{
C c1, c2;

c1.alter();

c2 = c1; // Why does this also make a copy of the array??

cout << " c2 is : " << endl;
c2.printA();

c1.alter();
cout << " c2 is still : " << endl;
c2.printA();

return 0;
}

----- END example CODE -----------

Instead, a copy of the array is made, so touching c1.A doesn't affect
c2.A.

Is this a _c++ standard_ behaviour? My lucky guess is that when you
use the default copy constructor, the object at the left of the
assignment gets the memory copied bit-to-bit from the one on the right
side, like a sort of "memcpy()" happens between the two.

So an array declared as an automatic variable in c1 gets its content
copied in the new object (c2) rather than simply the address it's
pointing to, since all the space taken by the array is sequentially
allocated in memory along with other vars declared in the class scope.

Hope my english is understandable enough...
Matteo
Jul 22 '05 #1
21 3948
"Matteo Settenvini" <ms*********@ti n.it> wrote in message
news:8e******** *************** ***@posting.goo gle.com...
Ok, I'm quite a newbie, so this question may appear silly. I'm using
g++ 3.3.x.
I had been taught that an array isn't a lot different from a pointer
It is very different. However the ability to use identical
syntax when using them can obsure the differences.
(in fact you can use the pointer arithmetics to "browse" it).
Yes.
So I
expected that when I run this program, I get both c1.A and c2.A
pointing to the same address,
Neither one points anywhere. They're not pointers, they're arrays.
They don't store addresses, they store integers.
and changing c1.A means that also c2.A
changes too.
No. They're completely separate objects. Neither c1
nor c2 contains any pointers.


----- BEGIN example CODE -----------

#include <iostream>
using std::cout;
using std::endl;

class C {
private :
int A[3];

public:
C() { for( int i=0; i<3; i++ ) A[i] = 0; };
void alter() { A[1]++; };
void printA() const;
};

void
C::printA() const
{
for( int i=0; i<3; i++ )
cout << "A[" << i
<< "] is " << A[i]
<< endl;
}

int
main( )
{
C c1, c2;

c1.alter();

c2 = c1; // Why does this also make a copy of the array??
It copies the entire contents of the object 'c1' to the
object 'c2'. The previous content of 'c2' is completely
overwritten. The array is part of the contents that's
why it's overwritten.

Since you've not defined your own assignement operator,
this works exactly like assignment for any other type.


cout << " c2 is : " << endl;
c2.printA();

c1.alter();
cout << " c2 is still : " << endl;
c2.printA();

return 0;
}

----- END example CODE -----------

Instead, a copy of the array is made, so touching c1.A doesn't affect
c2.A.

Is this a _c++ standard_ behaviour?
Yes. You wrote the statement which expresses:
"give 'c2' the same value as 'c1'.
If you write your own assignment operator for
class 'C', then you can define a new meaning
for 'assign'.
My lucky guess is that when you
use the default copy constructor,
Do copy ctor is invoked in your code above.
the object at the left of the
assignment gets the memory copied bit-to-bit from the one on the right
side, like a sort of "memcpy()" happens between the two.
Almost.

Not bit by bit, but member by member. This allows for the
cases where some members are of other class types which
might have their own creation and assigment semantics defined.
Copying byte by byte would subvert those operations.
So an array declared as an automatic variable in c1
You're using the wrong terminology. The array 'A' is
a 'nonstatic data member'. It is its containing object,
'c1' that has automatic storage duration. This effectively
gives its members the same duration, but only that of 'c1'.
So if 'c1' were defined as e.g. static, 'A' is certainly
not 'automatic'.

gets its content
copied in the new object (c2) rather than simply the address it's
pointing to,
There are *no* pointers in your code. *Nothing* is being
'pointed to'.
since all the space taken by the array is sequentially
allocated in memory along with other vars declared in the class scope.

Hope my english is understandable enough...


I think understand what you're writing, and I also think
you don't understand about arrays and/or pointers. This
is a big reason why I and others tell beginners to avoid
them and use the standard containers instead. E.g. anything
you can do with an array can be done with a std::vector.

BTW who is teaching you and which book(s) are you studying?

-Mike

Jul 22 '05 #2
Matteo Settenvini wrote:
I had been taught that an array isn't a lot different from a pointer
You were taught wrong. You should get a new teacher.
Arrays and pointers are completely different concepts. They
are distinct types. A pointer used to "browse" an array points
at exactly one object within it. The thing that reinforces this
conclusion is an ill-advised conversion from array to pointer to
it's first member that happens.

c2 = c1; // Why does this also make a copy of the array??
Yes, c1 and c2 each have a three element array of int called "A".
The assignment will copy c1.A's elements to c2.A. This is despite
the unfortunate lack of an assignment operator for array types, each
member is copied with it's assignment behavior.

Instead, a copy of the array is made, so touching c1.A doesn't affect
c2
The copy isn't made at the assignment, each object of type C gets the
three element array you declared as soon as it is created.

Is this a _c++ standard_ behaviour? My lucky guess is that when you
use the default copy constructor, the object at the left of the
assignment gets the memory copied bit-to-bit from the one on the right
side, like a sort of "memcpy()" happens between the two.
The copy constructor is NOT used here, what is happening is the implicitly
defined (I prefer to say that rather than default, because default default
cosntructor is confusing) copy-assignment operator performs a member wise
copy on each thing. It's not "sort of memcpy", each member is copied via
it's assignment operator (either implicit or user-defined) and in the case of
the array, each member of the array is copied.

So an array declared as an automatic variable in c1 gets its content
copied in the new object (c2) rather than simply the address it's
pointing to, since all the space taken by the array is sequentially
allocated in memory along with other vars declared in the class scope.


The array is NOT an automatic variable. It is a member variable of the
class. The address isn't copied because it's not a pointer. If it were
a pointer, then the pointers would be assigned. It's an array, so the
array elements are assigned.
Jul 22 '05 #3
Matteo Settenvini wrote:
Ok, I'm quite a newbie, so this question may appear silly. I'm using
g++ 3.3.x.
I had been taught that an array isn't a lot different from a pointer
(in fact you can use the pointer arithmetics to "browse" it). So I
expected that when I run this program, I get both c1.A and c2.A
pointing to the same address, and changing c1.A means that also c2.A
changes too.

----- BEGIN example CODE -----------

#include <iostream>
using std::cout;
using std::endl;

class C {
private :
int A[3];

public:
C() { for( int i=0; i<3; i++ ) A[i] = 0; };
void alter() { A[1]++; };
void printA() const;
};

void
C::printA() const
{
for( int i=0; i<3; i++ )
cout << "A[" << i
<< "] is " << A[i]
<< endl;
}

int
main( )
{
C c1, c2;

c1.alter();

c2 = c1; // Why does this also make a copy of the array??
Because the array is a member. Copy assignment applies assignment
semantics (not necessarily the assignment operator) to all members.
For members that are arrays it means element-wise copy-assignment.

cout << " c2 is : " << endl;
c2.printA();

c1.alter();
You're altering the contents of c1 object.
cout << " c2 is still : " << endl;
c2.printA();

return 0;
}

----- END example CODE -----------

Instead, a copy of the array is made, so touching c1.A doesn't affect
c2.A.
Of course. c1 and c2 are two different objects.

Is this a _c++ standard_ behaviour?
It's the "standard" behaviour of any OO language. Any [non-static] data
members are allocated in the memory set aside for the object that contains
them.
My lucky guess is that when you
use the default copy constructor, the object at the left of the
assignment gets the memory copied bit-to-bit from the one on the right
side, like a sort of "memcpy()" happens between the two.
No, not bit-to-bit. Member-by-member, element-by-element. Members and
elements of arrays are not necessarily 'int'. If they are other class
objects, assignment semantics will mean that operator= is called for them.

So an array declared as an automatic variable in c1
It's not "automatic" . It's a _data_member_.
gets its content
copied in the new object (c2) rather than simply the address it's
pointing to, since all the space taken by the array is sequentially
allocated in memory along with other vars declared in the class scope.


Right

V
Jul 22 '05 #4

"Matteo Settenvini" <ms*********@ti n.it> schrieb im Newsbeitrag
news:8e******** *************** ***@posting.goo gle.com...
Ok, I'm quite a newbie, so this question may appear silly. I'm using
g++ 3.3.x.
I had been taught that an array isn't a lot different from a pointer
(in fact you can use the pointer arithmetics to "browse" it). So I
expected that when I run this program, I get both c1.A and c2.A
pointing to the same address, and changing c1.A means that also c2.A
changes too.

----- BEGIN example CODE -----------

#include <iostream>
using std::cout;
using std::endl;

class C {
private :
int A[3];

public:
C() { for( int i=0; i<3; i++ ) A[i] = 0; };
void alter() { A[1]++; };
void printA() const;
};

void
C::printA() const
{
for( int i=0; i<3; i++ )
cout << "A[" << i
<< "] is " << A[i]
<< endl;
}

int
main( )
{
C c1, c2;

c1.alter();

c2 = c1; // Why does this also make a copy of the array??

cout << " c2 is : " << endl;
c2.printA();

c1.alter();
cout << " c2 is still : " << endl;
c2.printA();

return 0;
}

----- END example CODE -----------

Instead, a copy of the array is made, so touching c1.A doesn't affect
c2.A.

Is this a _c++ standard_ behaviour? My lucky guess is that when you
use the default copy constructor, the object at the left of the
assignment gets the memory copied bit-to-bit from the one on the right
side, like a sort of "memcpy()" happens between the two.

[SNIP]

Yes, this is standard behavior. If you do not supply a copy constructor,
assignment operator or destructor the compiler implements them for you. Try
to use a dynamically allocated array instead and run your code again. Then
you will see that the bit-wise copy, or assignment respectively, results in
the behavior you expected because not the value pointed to but rather the
pointer is copied or assigned. However, most of the time you would expect a
copy to be a real "copy" and do not want to end up with two different
objects pointing at the same memory. Consequently you have to implement the
copy constructor yourself. Following the "rule of three" you should also go
ahead and implement the destructor and the assignment operator too. If you
need one of the aforementioned you'll most likely need all of them.

HTH
Chris
Jul 22 '05 #5
Probably it's me doing just a mess... anyway I'm using a book wrote by
some italians and also "Thinking in C++".

Sorry to appear so "newbieish" but from somewhere you've to start...

But why this isn't legal, then?

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

#include<iostre am>

int main()
{
int A[10], B[10];
A = B;
}
Jul 22 '05 #6
Matteo Settenvini wrote:
Probably it's me doing just a mess... anyway I'm using a book wrote by
some italians and also "Thinking in C++".

Sorry to appear so "newbieish" but from somewhere you've to start...

But why this isn't legal, then?

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

#include<iostre am>

int main()
{
int A[10], B[10];
A = B;
}


It's not legal because arrays are not assignable. IOW, an object of
type "array of T" cannot appear on the left side of an assignment op.

V
Jul 22 '05 #7
arrays are really pointers to data in memory.

A[10] is a pointer to 10 ints in memory (at least the space is assigned),
contiguous one right after the other.

A = B; // this is trying to assign the B array to the A array, but won't
work unless it's from a class with a copy constructor.

*A = *B; // this will work because it reassigns the A pointer....
/* but this will lead to a memory leak because the array A was
assigned to is now stuck in memory without a way to access the values, the
array is now lost into the memory. if you do want to have two pointers to
the same object, then declare an int* A pointer instead and assign it to B[]
what this leads to is two pointers where either one can change the data
without the other pointer this can be bad because large programs may have
these two pointers and your program may output both at different times
leading to something unexpected since they point to the same data. The best
way to have two arrays is to implement a copy constructor for a class or
simply a copy function if the arrays are not part of a class. */

Brad
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:S6******** ********@newsre ad1.dllstx09.us .to.verio.net.. .
Matteo Settenvini wrote:
Probably it's me doing just a mess... anyway I'm using a book wrote by
some italians and also "Thinking in C++".

Sorry to appear so "newbieish" but from somewhere you've to start...

But why this isn't legal, then?

----------------
#include<iostre am>

int main()
{
int A[10], B[10];
A = B;
}


It's not legal because arrays are not assignable. IOW, an object of
type "array of T" cannot appear on the left side of an assignment op.

V

Jul 22 '05 #8
"Brad Herald" <bh*****@vt.edu > wrote in message news:<cl******* ***@solaris.cc. vt.edu>...
arrays are really pointers to data in memory.
oh, well, are they pointers or not? someone tells me they are _really_
pointers, someone that they _aren't_.

A[10] is a pointer to 10 ints in memory (at least the space is assigned),
contiguous one right after the other.
right.

A = B; // this is trying to assign the B array to the A array, but won't
work unless it's from a class with a copy constructor.

*A = *B; // this will work because it reassigns the A pointer....


I thought that this should means:

A[] = { 1, 2, 3 };
B[] = { 4. 5. 6 };

*A = *B;

then you get:

A[] = { 4, 2, 3 };

Obviously, if the two arrays were created with the "new" kw (and thus
int**), what you say makes sense, but that's a different problem.

Anyway, the problem is:
- when I assign directly two pointers I get a compilation error
- when I assign two objects that are of type C, and C is a class that
contains an array as a member, the array is copied and no error is
returned.

is it because I'm creating the class members "ex novo" with a
temporary object when copying them (at runtime?), while both the
arrays in the main() both exist before assignment?
Jul 22 '05 #9
Matteo Settenvini wrote:
"Brad Herald" <bh*****@vt.edu > wrote in message news:<cl******* ***@solaris.cc. vt.edu>...
arrays are really pointers to data in memory.

oh, well, are they pointers or not? someone tells me they are _really_
pointers, someone that they _aren't_.


Arrays are not pointers. Using the name of an array in an expression
yields a pointer to the first element, yes. That does NOT automatically
make arrays pointers. The act of converting arrays to pointers is often
called "decay", as in "array name decays to a pointer to the first array
element". This conversion is described/defined in subclause 4.2 of the
Standard.
A[10] is a pointer to 10 ints in memory (at least the space is assigned),
contiguous one right after the other.
Nonsense. A[10] by itself is an expression *(A + 10). In a declaration

int A[10];

'A' has type 'an array of 10 ints'. It is NOT a pointer.
right.
Nope.
A = B; // this is trying to assign the B array to the A array, but won't
work unless it's from a class with a copy constructor.
Nonsense again. A copy constructor has NOTHING to do with this. For
arrays it simply won't work.

*A = *B; // this will work because it reassigns the A pointer....


In this expression both A and B decay to the pointers to the first
elements of the respective arrays (assuming they are arrays) and the
expression is essentially the same as

A[0] = B[0];


I thought that this should means:

A[] = { 1, 2, 3 };
B[] = { 4. 5. 6 };
The two lines above are not C++.

*A = *B;

then you get:

A[] = { 4, 2, 3 };
I am guessing at this point you're just trying to illustrate what the
values of the elements are, and not writing C++ code. Then, yes.

Obviously, if the two arrays were created with the "new" kw (and thus
int**),
Huh?
what you say makes sense, but that's a different problem.

Anyway, the problem is:
- when I assign directly two pointers I get a compilation error
Huh? Code, please.
- when I assign two objects that are of type C, and C is a class that
contains an array as a member, the array is copied and no error is
returned.
That's correct.
is it because I'm creating the class members "ex novo" with a
temporary object when copying them (at runtime?), while both the
arrays in the main() both exist before assignment?


What?

When an object of a class type is assigned a value of another object of
the same class type, _copy_ assignment operator is invoked. That operator
is a special function. If you don't declare/define one yourself, the
compiler provides it for you. The compiler-provided copy assignment
operator invokes _copying_ for every member. It does NOT invoke operator=
_literally_ for all members, although you could think of it that way. The
data members that are arrays are an exception, essentially. It was done
for backward compatibility with C, where copying is basically bit-by-bit,
because they don't have other copy semantics than that.

If a data member is an array of T, all elements of that array are copied
using their copy semantics. I.e., if they are classes, operator= is used.
If they are built-in classes, internal means are used to copy them.

V
Jul 22 '05 #10

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

Similar topics

13
17521
by: franky.backeljauw | last post by:
Hello, following my question on "std::copy versus pointer copy versus member copy", I had some doubts on the function memcpy, as was used by tom_usenet in his reply. - Is this a c++ standard library function? That is, can I be sure that every c++ standard library has this function? Or is there a c++ alternative to it?
8
4647
by: Thomas Mlynarczyk | last post by:
Hi! If A is an object, then "B = A;" will just assign a reference. Isn't there a simple way to create an actual copy of A and assign that to B? Greetings, Thomas
10
2402
by: Cocy | last post by:
Hi, This might be a sort of FAQ, but I don't see why, so I would someone help me to understand what's wrong? I've just created following code which wold trim white space(s) in a (given) string. But, it resulted the Segmentation fault, and so as when running in gdb (saying "Program received signal SIGSEGV, Segmentaion fault at *p++ = *st++"). The platform is Linux kernel 2.4.27, gcc version
11
4480
by: truckaxle | last post by:
I am trying to pass a slice from a larger 2-dimensional array to a function that will work on a smaller region of the array space. The code below is a distillation of what I am trying to accomplish. // - - - - - - - - begin code - - - - - - - typedef int sm_t; typedef int bg_t; sm_t sm; bg_t bg;
1
8297
by: Mark Smith | last post by:
I'm trying to copy data from a 1D array to a 2D array. The obvious thing doesn't work: int twoDee = new int; int oneDee = new int { 1, 2 }; Array.Copy(oneDee, 2, twoDee, 2, 2); This causes a RankException. But the MSDN documentation says: When copying between multidimensional arrays, the array
5
3297
by: Victor Bazarov | last post by:
Below you will find some code I wrote to see if I could wrap array copying (especially for multi-dimensional arrays) in a simple class and/or function. It seems to work fine for one-dimensioned arrays as well as two-dimensioned ones. I am sure three- or more-dimensioned array are just as OK here. My concern was that I couldn't use 'std::copy' to copy multi-dimensional arrays. Perhaps in the future we'll see specialisations of...
5
2565
by: Frederick Gotham | last post by:
I want to copy an array of objects. If it were C, I'd simply do: memcpy( target_array, source_array, sizeof target_array ); However, this won't suffice for objects in C++.
0
9892
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
9734
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
10991
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...
0
10347
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9490
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...
0
5915
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4540
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
2
4129
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3168
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.