2

I have a program with one structnamed sample, it contains 2 int members and one char *. when creating 2 objects called a and b, I try assign a new dynamic string to a with the pointer and then copy all the values to b. so b = a. But later on when try to make changes to a like this : a.ptr[1] = 'X'; the pointer in b also changes. I want to know why, and how can I solve this.

struct Sample{
    int one;
    int two;
    char* sPtr = nullptr;
};
int _tmain(int argc, _TCHAR* argv[])
{
    Sample a;
    Sample b;
    char *s = "Hello, World";
    a.sPtr = new char[strlen(s) + 1];
    strcpy_s(a.sPtr, strlen(s) + 1, s);
    a.one = 1;
    a.two = 2;
    b.one = b.two = 9999;



    b = a;
    cout << "After assigning a to b:" << endl;
    cout << "b=(" << b.one << "," << b.two << "," << b.sPtr << ")" << endl << endl;

    a.sPtr[1] = 'X' ;
    cout << "After changing sPtr[1] with 'x', b also changed value : " << endl;
    cout << "a=(" << a.one << "," << a.two << "," << a.sPtr << ")" << endl;
    cout << "b=(" << b.one << "," << b.two << "," << b.sPtr << ")" << endl;

    cout << endl << "testing adresses for a and b: " << &a.sPtr << " & b is: " << &b.sPtr << endl;



    return 0;
}
Juan Mar
  • 59
  • 7
  • Can you post the output of running this code fragment? – kdopen Dec 17 '14 at 20:51
  • After assigning `b` to `a`, the values of all the members of `b` are copies of the value in `a`, including the pointer (pointers are values too, that just happen to be interpretable as addresses). So both `a` and `b` have pointers pointing to the same location in memory -- and changing that memory has nothing to do with either `a` or `b`, since all their pointers do is merely point at that (same) location. Does that help? – Cameron Dec 17 '14 at 20:52
  • possible duplicate of [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – mpromonet Dec 17 '14 at 21:32

2 Answers2

3

Your struct contains a char*. When you assign all values in a to b, the pointer is also copied.

This means that a and b now point to the same char array. Therefore changing a value in this char array changes it for both structs.

If you do not want this, make a new char array for b and use strcpy.

Jesse
  • 315
  • 2
  • 8
  • I'd much rather suggest using `std::string` instead of this. There might be reasons for using such arrays, but that is low-level programming that people shouldn't attempt if they are still struggling with the C++ object model. – Ulrich Eckhardt Dec 17 '14 at 20:58
  • 1
    Agreed iff the author is going for the C++ object model. The code fragment combines both C and C++. – Jesse Dec 17 '14 at 21:06
  • OP is not using the OO approach, therefore std::string is not needed. – 2501 Dec 17 '14 at 21:07
  • I can't follow your reasoning, @2501. Even if your program doesn't need any OOP, you still benefit from using higher-level datatypes like `std::string`. – Ulrich Eckhardt Dec 18 '14 at 11:46
2

You are copying the pointer not the value. To solve this you could override your assignment operator in the structure:

struct Sample{
    int one;
    int two;
    char* sPtr = nullptr;
    Sample& operator=(const Sample& inputSample)
    {
        one = inputSample.one;
        two = inputSample.two;
        sPtr = new char[strlen(inputSample.sPtr) + 1];
        strcpy (sPtr, inputSample.sPtr);
        return *this;
    }
};
Jérôme
  • 8,016
  • 4
  • 29
  • 35