1

Why is Destructor Called in this Friend function show() C++? Also, how should the character pointer be initialized, it was set as 0... The full code with main is here https://justpaste.it/5x7fy

#include<iostream>
using namespace std;
#include<string.h>

class String
{

public:
    char *p;
    int len;
    String()
    {
        cout << "empty constructor" << endl;
        len=0;
        p=0;
    }
    // constructor
    String(const char *s) {
        len=strlen(s);
        p=new char[len+1];
        strcpy(p,s);
    }

    friend String operator+(const String&s, const String&t);
    friend int operator<=(const String&s, const String&t);
    friend void show(const String s);

    ~String() {delete p;}
};

void show(const String s)
{
    cout<<s.p<<endl;
}

Edit, read up on copy constructor and added one as:

// copy constructor
String(const String &s)
{
    len=s.len;
    p=new char[len+1]; // s.p;//
    strcpy(p,s.p);
}

The friend function parameter was passed by value before and the variable left the show function scope, therefore the destructor was called, now it is passed by reference.

    friend void show(const String & s);
...
    void show(String & s)
    {
        cout<<s.p<<endl;
    }

Edit updated the initialization of the character pointer in the empty constructor.

String() {
    p = new char[1]{'\0'};
    len = 1;
};

[latest source]: https://www.mediafire.com/file/31gb64j7h77x5bn/class38working.cc/file

Hugo R
  • 25
  • 3
  • Not what you asked about, but neither your code above nor the full code linked has correct copying semantics. So that destructor call, while correct, is likely to crash your program. – john Apr 18 '20 at 19:39
  • 2
    Seriously, teachers should stop teaching about memory leaks before they teach about [the rule of three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Forgetting to delete memory is harmless in most cases, the programs end quickly anyway, deleting in destructor without proper copy constructor is UB. – Yksisarvinen Apr 18 '20 at 19:42
  • @Yksisarvinen yes and the copy constructor is not working when initializing this way.} `String string3 = s1+s2` – Hugo R Apr 18 '20 at 20:10

2 Answers2

4

The destructor is called because s is passed by value. That is, when you call show(something), that something is copied into s, which is later destroyed when execution of show ends.

numzero
  • 2,009
  • 6
  • 6
  • good call that was it, adding a & to the function signature, made it pass by reference right? So now it is running ***show()*** function without calling destructor afterwards. – Hugo R Apr 18 '20 at 19:42
  • `const String &` is a reference to const `String`; likewise `String &` is a reference to `String`. So yes, adding that make it pass by reference. – numzero Apr 18 '20 at 19:59
  • @HugoR Just noticed your class has no copy constructor (that taking single `const String&` argument) declared. That means the compiler generates one for you. Sadly what it does is different from what you want: it only copies all the fields, so you end up with two `String` instances having the same `p` value. You need to implement the copy constructor yourself. – numzero Apr 18 '20 at 20:02
  • The copy constructor is in the edit, you can have a look. – Hugo R Apr 19 '20 at 23:29
  • The copy constructor is okay, assuming that `len == strlen(p)` – numzero Apr 21 '20 at 13:44
  • Whoops, one subtle problem. If the string is empty, `p` is either NULL or points to nowhere. Neither case is supported by `strcpy`: an empty C string actually consists of one byte, the terminator, so needs to be created like `p = new char[1]{'\0'};` (or handled in a special way everywhere). – numzero Apr 21 '20 at 13:50
0

Your friend function show takes the String parameter per value, which means that whatever argument is passed to the function, a local copy is created and used inside the function. Of course, this local copy is destroyed - again when the show() function ends.

If you pass the string by reference (const string**&** s), you won't get an extra temp copy nor any destruction of that.