I give the code of the overloaded method (some kind of slices) in which a memory leak occurs. Help please find exactly where. Is the local variable temp to be destroyed?
Why does the function not work when assigned temp.size = 0 and works at 11..1? The size class field is used to keep track of the status of a method call. (In case this is the second method call, the size of the string will not match the size field.)

struct String { String(const char *str = "") { this->size=strlen(str); this->str=new char [size+1]; for(int i=0; i < this->size; i++) this->str[i]=str[i]; this->str[size]='\0'; } ~String() { delete [] str; } String(const String &other) { this->size=other.size; this->str=new char [size+1]; for (int i=0; i<=this->size; i++) this->str[i]=other.str[i]; } String& operator=(const String &other) { this->~String(); this->size=other.size; this->str=new char [size]; for (int i=0; i<size; i++) this->str[i]=other.str[i]; return *this; } String operator[](const int ii) const { String temp; if (this->size == strlen(this->str)) { if (ii != 0) temp.size = this->size; else temp.size=111111; temp.str = new char[this->size - ii]; for (int i = ii; i < this->size; i++) temp.str[i - ii] = this->str[i]; } else { if (this->size==111111) temp.size=ii; else temp.size=strlen(this->str)+ii-this->size; temp.str=new char [temp.size]; for (int i=0; i<temp.size; i++) temp.str[i]=this->str[i]; } return temp; } public: size_t size; char *str; }; ostream& operator<<(ostream & os, const String &a) { os << a.str; return os; } int main() { String a; a=String("asdasd"); String b=a[2][3]; b=a[0][2]; cout << b << endl; String const hello("hello"); String const hell = hello[0][4]; // теперь в hell хранится подстрока "hell" String const ell = hello[1][4]; // теперь в ell хранится подстрока "ell" cout << hello << " " << hello.size << endl; cout << hell << " " << hell.size << endl; cout << ell << " " << ell.size << endl; return 0; } 
  • 2
    There is a new - no delete - memory leak. - user212277
  • Shouldn't the class destructor be called after the closing bracket? ~ String () {delete [] str;} - Vladimir Vlasenko
  • And show class destructor String . - VladD
  • ~ String () {delete [] str; } - Vladimir Vlasenko
  • 2
    Your String class does not seem to have a copy / move constructor. And therefore, calling the destructor, you delete the line inside. And the pointer to the remote memory will come to the calling code. - KoVadim

1 answer 1

Your constructors contain obvious errors. For a start, they are not equivalent. That is, they will create different objects.

the copy constructor allocates enough space, but forgets about the null character at the end

 String(const String &other) { this->size=other.size; this->str=new char [size+1]; for (int i=0; i<=this->size; i++) this->str[i]=other.str[i]; this->str[this->size] = '\0'; } 

But you can write shorter, if you are already writing in si style.

 String(const String &other) { this->size=other.size; this->str=new char [size+1]; strncmp(this->str, other.str, other.size); this->str[this->size] = '\0'; } 

Calling destructor in operator= is interesting :) I would write at least that way.

 String& operator=(const String &other) { delete[] this->str; this->size=other.size; this->str=new char [size+1]; for (int i=0; i<size; i++) this->str[i]=other.str[i]; this->str[this->size] = '\0'; return *this; } 

UPD

Minimally corrected the code to remove leaks (although they were not there) and all sorts of memory shootings.

 #include <iostream> #include <cstring> using namespace std; struct String { String(const char *str = "") { this->size=strlen(str); this->str=new char [size+1]; for(int i=0; i < this->size; i++) this->str[i]=str[i]; this->str[size]='\0'; } ~String() { delete [] str; } String(const String &other) { this->size=other.size; this->str=new char [size+1]; for (int i=0; i<=this->size; i++) this->str[i]=other.str[i]; this->str[size] = '\0'; } String& operator=(const String &other) { delete[] this->str; this->size=other.size; this->str=new char [size+1]; for (int i=0; i<size; i++) this->str[i]=other.str[i]; this->str[size] = '\0'; return *this; } String operator[](const int ii) const { String temp; if (this->size == strlen(this->str)) { if (ii != 0) temp.size = this->size; else temp.size=111111; delete[] temp.str; temp.str = new char[this->size - ii+1]; for (int i = ii; i < this->size; i++) temp.str[i - ii] = this->str[i]; temp.str[this->size - ii] = '\0'; } else { if (this->size==111111) temp.size=ii; else temp.size=strlen(this->str)+ii-this->size; delete[] temp.str; temp.str=new char [temp.size+1]; for (int i=0; i<temp.size; i++) temp.str[i]=this->str[i]; temp.str[temp.size] = '\0'; } return temp; } public: size_t size; char *str; }; ostream& operator<<(ostream & os, const String &a) { os << a.str; return os; } int main() { String a; a=String("asdasd"); String b=a[2][3]; b=a[0][2]; cout << b << endl; String const hello("hello"); String const hell = hello[0][4]; // теперь в hell хранится подстрока "hell" String const ell = hello[1][4]; // теперь в ell хранится подстрока "ell" cout << hello << " " << hello.size << endl; cout << hell << " " << hell.size << endl; cout << ell << " " << ell.size << endl; return 0; } 

True, what makes size = 111111 I did not understand. It looks like a spooky crutch.

PS while looking at the code, I realized that I had already seen this code on ru.stackoverflow.com. And even corrected similar errors.

  • Thanks, corrected, changed the code several times and didn’t notice that I’ve been naughty. But the leak is in the operator [] method. I also wanted to clarify with operator =, why shouldn't the destructor be called? Would it be logical to release a variable if we assign another value to it? - Vladimir Vlasenko
  • If you suspect a memory leak, create a minimal example that plays a space and lay out the full code. - KoVadim
  • This is a learning task for the course in which you only need to implement the operator []. There are several workarounds and simpler ways to solve a problem using additional classes. But in the discussions the teachers said that this is not a very good way, and therefore I want to defeat the leak in order to understand the issue more thoroughly. The code resulted. - Vladimir Vlasenko
  • Training course this ? - KoVadim
  • Yes, this course. The leak still remained. - Vladimir Vlasenko