0
#include <iostream>
using namespace std;

class B
{
    int a = 10;
    int b = 20;
    int A[5] = {1, 2, 3, 4, 5};// int *A = new int[5]{1, 2, 3, 4, 5};

public:
    friend void change(B);

    void print()
    {
        for (int i = 0; i < 5; i++)
        {
            cout << " " << A[i];
        }

        cout << endl;
    }
};

void change(B obj)
{
    int *p = obj.A;
    for(int i = 0; i < 5; i++)
    {
        *p += 10;
        p++;
    }
}

int main()
{
    B first;
    first.print();
    change(first);
    first.print();
    change(first);
    first.print();
    return 0;
}

Here, A is holding the base address of the array, and when I am calling the function change() then a pointer (p) in the function is holding the address of the address of A that is in the base class. So, I think that it should change the value of the data of the object in the array, and it should print the value as:

1 2 3 4 5
11 12 13 14 15
21 22 23 24 25

But it's not going like that, it is printing this:

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

But, when I am making the array on the heap using int *A=new int[5]{1, 2, 3, 4, 5}; then it works as I expect.

So, how will I know when the value of the data will change and when the data will not change? In both cases, A has the pointer to the address of the original array, but in the one case it is changing the value, while in the other case it's not changing, Why? Please explain to me in detail.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The reason it "works as expected" is because your `class B` does not implement a copy constructor, making the use of `new` in it violating the rule of 3, which would break your entire code if you weren't leaking the memory – UnholySheep Oct 08 '22 at 19:08
  • *"in the base class"* -- there is no inheritance in your code, so there is no base class. I do not know what you intended here. My best guess is that you meant the variable `first` in the main function, but that is an object, not a class, and it's out of scope inside `change()`. – JaMiT Oct 09 '22 at 17:43

1 Answers1

1

In the case of int A[5] = {1, 2, 3, 4, 5};, A DOES NOT contain the base address of the array, A IS the array itself. The whole memory of the array is contained within the memory of the B object. So, every instance of B has its own array, and when you call change() passing it a B object by value, a copy of the object is made, thus making a copy of the array. The function is then modifying the copied array, not the original array. That is why you do not see the data in main() being changed.

In the case of int *A = new int[5]{1, 2, 3, 4, 5};, A DOES contain the base address of the array, A IS NOT the array itself. The array is stored elsewhere in memory, and A just points at it. So, every instance of B initially has its own array, but when you call change() passing it a B object by value, a copy of the object is made, thus making a copy of the pointer to the array (violating the Rule of 3/5/0), the actual array itself is not copied. The function is then using the copied pointer to modify the original array, not a copy of the array. That is why you do see the data in main() being changed.

To fix the 2nd case, you need to implement a copy constructor (and copy assignment operator) in B to make a copy of the array (and you need a destructor to free the array).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Here How i will know that when the address of the original and the when the address of the copied data will get stored – Harsh Kumar Oct 09 '22 at 13:54
  • When an object is copied by value, and the class does not explicitly implement a copy constructor, a default generated copy constructor merely copies the class fields by value. In the 1st case, `A` is the actual array, so the array is copied. In the 2nd case, `A` is just a pointer to the array, the pointer is copied, not the array. It really sure how to make that clearer for you. – Remy Lebeau Oct 09 '22 at 22:22
  • Here is the link of the question asked by me https://stackoverflow.com/questions/74005913/how-to-know-that-when-the-original-data-will-get-the-modified-and-the-when-not .The first code you have already make me understand but in the 2nd code also when i am passing the object first in the function then an array should be made for the obj and the pointer p should point the array of the obj and the change should not be done on the array of the first array Then why here the change is happening. Please explain me all concept related to this . – Harsh Kumar Oct 10 '22 at 05:41
  • @HarshKumar In your other question (which has been deleted), you were making a copy of the array itself, but you were also making a copy of a pointer that was pointing at the original array, not the copied array. Hense why the original was modified. Similar to the code in this question, when using `new` and then copying that pointer. I get the feeling that you don't really understand what pointers actually are, and how memory works. I strongly suggest you get yourself some [good C++ books](https://stackoverflow.com/questions/388242/) to learn from. – Remy Lebeau Oct 10 '22 at 16:37