Почему этот код висит в указанном месте? - PullRequest
0 голосов
/ 12 сентября 2011

Это наивный пример, который я написал для изучения перегрузки операторов C ++. Когда я его выполняю, код зависает в операторе c = a + b; и контроль никогда не достигает c.display();

В качестве части отладки, если я помещаю cout << ptr << '\n'; в перегруженную функцию оператора присваивания, она выводит HelloWorld, поэтому строка не выглядит искаженной.

Почему это зависает тогда? Чего мне не хватает ??

class mystring
{
    char *ptr;

    public:

   mystring(char *str = "")
   {
      ptr = new char[strlen(str) + 1];
      strcpy(ptr,str);

   } 

   mystring operator +(mystring s)
   {
      char *str = new char[strlen(ptr) + strlen(s.ptr) + 1];//where should this memory be freed
      strcpy(str,ptr);
      strcat(str,s.ptr);
      return mystring(str);
   }

   void operator =(mystring s)
   {
       strcpy(ptr,s.ptr);

      //cout << ptr << '\n'; \\Debug - this prints out HelloWorld but still hangs 
   }

   void display()
   {
       cout << ptr << '\n';
   }

   ~mystring()
   {
      delete [] ptr; 
   }
};

int main()
{
   mystring a="Hello",b="World",c;

  c = a + b;

  c.display();

  getchar();

}

РЕДАКТИРОВАТЬ: Компилятор: MS-Visual C ++ 2010 Express / Windows.

Ответы [ 5 ]

1 голос
/ 12 сентября 2011

Я думаю, что вы получаете ошибку памяти.Эта строка:

c = a + b;

выполняет следующие действия:

c.constructor()
c.operator=(a.operator+(b));

и ваш оператор = не может выделить память

void operator =(mystring s)
{
  // ptr is allocated enough memory for "", i.e. one byte
  strcpy(ptr,s.ptr); // copying more than one byte into one byte array
  //cout << ptr << '\n'; // this works, but you've trashed memory with the strcpy
} // stack might be corrupted here, depends where this is, so execution can end up anywhere

Что вам нужно:

void operator = (mystring &s) // reference!
{
  delete [] ptr;
  ptr = new char [strlen (s.ptr + 1)];
  strcpy (ptr, s.ptr);
}
1 голос
/ 12 сентября 2011

char * str = new char [strlen (ptr) + strlen (s.ptr) + 1]; // где должна быть освобождена эта память

Память освобождена на деструкторе.

Оператор = вы должны освободить выделенную память и снова выделить ее

1 голос
/ 12 сентября 2011

ваш operator= сломан. Вы неправильно распределяете достаточно (или вообще ничего) памяти перед выполнением strcpy. Это приводит к неопределенному поведению.

0 голосов
/ 12 сентября 2011

Кажется, что в коде нет очевидной проблемы, из-за которой он блокируется перед нажатием c.display(), но он может выглядеть так, как он это делает.

Операция cout << ptr << '\n'; не очищает поток, а это означает, что выходные данные могут быть кэшированы до более позднего времени.Может случиться так, что вся программа завершила в основном и ждет, когда пользователь введет символ в getchar().

Попробуйте запустить код в отладчике или измените вывод на cout << ptr << endl;.

Кстати: вы теряете память в operator+ и, вероятно, должны позаботиться об этом.Я знаю, что вы уже спрашивали о том, как это сделать, возможно, вам не понравились (или не поняли) решения, которые были предложены, но оставить это как есть - не решение.

operator= не гарантирует, чтоу вас достаточно места для хранения всей строки, что означает, что вы можете инициировать неопределенное поведение.

0 голосов
/ 12 сентября 2011

operator = должен освободить старый буфер, а затем выделить новый, как вы делаете в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...