0

From Java I'm used that I can do this:

public class SomeClass {
    public int field1;
}

SomeClass[] data = new SomeClass[10];
for (int i = 0; i < 10; i++) {
    data[i] = new SomeClass(); 
    SomeClass d = data[i];
    d.field1 = 10;
}

for (int i = 0; i < 10; i++) {
    SomeClass d = data[i];
    System.out.println("Value of data [" + i + "] is [" + d.field1 + "]");
}

And this will work fine, printing:

Value of data [0] is [10]
Value of data [1] is [10]
... etc

So in Java you first create the Array, which has by default all null values, and then in the first loop I create a new SomeClass and assign it to a slot in the array. If you don't do this you get a NullPointerException.

All fine.

The question: I try to do the same in C++. I have one failing and one working example. But I am unsure why it works (or does not work, depending what example you pick). Can anyone elaborate?

First, the failing code:

int main(int argc, char **argv) {
    MyClass data[10];
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "INITIALLY (garbage): [" << d.field1 << ", " << d.field2 << "] " << endl;
        // assign values
        d.field1 = 2;
        d.field2 = 3;
    }

    // print out data of first 10
    cout << "Printing out data after initialization" << endl;
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "[" << d.field1 << ", " << d.field2 << "] " << endl;
    }
}

So If i understand correctly, according to this StackOverflow question I can create an array of a Struct like I do in the above code.

What I noticed is that if I do not use:

MyClass d = data[y];
d.field1 = 2;
d.field2 = 3;

But instead I do:

data[y].field1 = 2;
data[y].field2 = 3;

It does work.

However, if I insist on using a separate value, I can still make it work by doing this:

MyClass * d = &data[y];
d->field1 = 2;
d->field2 = 3;

I do not change anything in printing the output. And the above works.

So, something clearly is different when using a pointer to data[y]. I cannot found a clear answer on this though. Anyone able to explain why?

If this question is a duplicate, sorry for that, I could not find a real answer on the "why" part. Code snippets are not always enough for me ;)

PPS: I am aware that I am not allocating this array in the heap. Bonus points for touching that subject to compare to :)

3 Answers 3

1

In C++, an object is a region of storage - that is, an area of memory. Variables denote objects directly, unless they are explicitly qualified as pointers or references to existing objects.

When you write:

MyClass d = data[y];

you are declaring a variable of type MyClass, defining it as denoting an object on the stack, and initialising it from the object data[y]; d and data[y] are separate objects so modifying d will not affect data[y].

You want to write:

MyClass &d = data[y];
        ^--- here

The ampersand & denotes d as a reference to the object data[y], so as long as an object continues to exist within the region of storage that data[y] originally denoted (i.e. at that address), you can use d to modify that object.

Using a pointer is similar, but because pointers can be reseated to point to a different object you must use indirection syntax (* or ->) to denote the object they point to.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow thanks a bunch! Really clear answer. Do you have any further reference for me to get a better understanding of these behaviours? For example, this is a one dimensional array. What If I'd like to have a two dimensional array? In Java things are just much easier to grasp. But I insist on doing this in C++. Again, thanks a lot!
1

This:

    MyClass d = data[y];
    d.field1 = 2;
    d.field2 = 3;

Has no effect because d is now a copy of data[y]. If you said MyClass& d instead, you'd have a (non-const) reference, which you could modify and then observe those changes in data.

Comments

1

You are making a copy here:

MyClass d = data[y];

Modifications to d have no impact on data[y].

Take a reference instead:

MyClass& d = data[y];

Now d refers to the element data[y]. Note that in C++ a reference behaves like an alias. You cannot re-assign it. For example

d = someMyClassInstance;

will have the effect of assigning the value of someMyClassInstance to data[y].

1 Comment

Thanks a lot! I did not realize I was creating a copy. It makes sense now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.