0

I am looking at the code and explanations from this page and I don't quite get it. https://www.geeksforgeeks.org/copy-constructor-in-cpp/

Below is the example I am confused on. why does str2.change("GeeksforGeeks"); cause str1 to also change? I ask because change does the exact same thing as the copy constructor. They both assign a new char array to s.

#include<iostream> 
#include<cstring> 
using namespace std; 

class String 
{ 
private: 
    char *s; 
    int size; 
public: 
    String(const char *str = NULL); // constructor 
    ~String() { delete [] s;  }// destructor 
    void print() { cout << s << endl; } // Function to print string 
    void change(const char *);  // Function to change 
}; 

String::String(const char *str) 
{ 
    size = strlen(str); 
    s = new char[size+1]; 
    strcpy(s, str); 
} 

void String::change(const char *str) 
{ 
    delete [] s; 
    size = strlen(str); 
    s = new char[size+1]; 
    strcpy(s, str); 
} 


int main() 
{ 
    String str1("GeeksQuiz"); 
    String str2 = str1; 

    str1.print(); // what is printed ? 
    str2.print(); 

    str2.change("GeeksforGeeks"); 

    str1.print(); // what is printed now ? 
    str2.print(); 
    return 0; 
} 
user1099123
  • 6,063
  • 5
  • 30
  • 35
  • 3
    Aren't you referring to the example where they *removed* the copy constructor? The example for this code does not change `str1` – UnholySheep Dec 28 '19 at 16:26
  • 4
    Your code fails miserably in a simple program `String s;`. That one line causes [undefined behavior](http://coliru.stacked-crooked.com/a/2ad635cfc343ae77) due to calling `strlen` on a null pointer. The geekstogeeks site is a place where you don't learn how to write C++ code properly. No way should a default initialization result in undefined behavior, but it does. – PaulMcKenzie Dec 28 '19 at 16:28
  • @UnholySheep you are right i've edited the code to remove the copy constructor – user1099123 Dec 28 '19 at 16:28
  • 1
    Without the copy constructor (technically with an implicitly defined copy constructor) the second call to `str1.print();` invokes *undefined behavior* as the pointed to array has been deleted by `str2.change` – UnholySheep Dec 28 '19 at 16:34
  • 1
    Undefined behavior. On your machine, by happenstance, the newly allocated `s = new char[size+1];` just so happens to be at the previous location the old character buffer used to be located. On my machine, it crashed. – Eljay Dec 28 '19 at 16:34
  • 2
    Also it is telling that no one in the comments on that page detected this glaring error with the default constructor. New programmers that go to that site now believe that the code is ok. – PaulMcKenzie Dec 28 '19 at 16:36
  • Thanks @PaulMcKenzie I will try to avoid geeks for geeks from now on – user1099123 Dec 28 '19 at 16:46
  • @user1099123 -- To be fair, geeksforgeeks is ok for learning *how* to solve a problem theoretically. The issue is that the code samples that convey their methods of solving problems are, for the most part, poorly coded. – PaulMcKenzie Dec 28 '19 at 20:20

1 Answers1

5

str2.change("GeeksforGeeks"); deletes the old memory str1 is still pointing to. Then str1.print() causes undefined behavior, thus anything may happen.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • 2
    Thanks man. I've come to the conclusion geeks for geeks while can be helpful, is not the best place to learn this stuff. – user1099123 Dec 28 '19 at 16:44
  • 1
    @user1099123 have you seen our [Definitive C++ Book Guide and List](https://stackoverflow.com/a/388282/10147399)? It's very useful. – Aykhan Hagverdili Dec 28 '19 at 16:47