Перегрузка + внутри класса - Ошибка отладки утверждения! - PullRequest
0 голосов
/ 03 декабря 2010

Я пытаюсь почувствовать перегрузку оператора, но столкнулся с проблемой.Программа предназначена только для двух строк.Я знаю, что есть и другие способы сделать это, но я хотел играть.Я получаю следующую ошибку:

file: dbgdek.cpp line: 52 _ASSERTE (_BLOCK_TYPE_IS_VALID (pHead-> nBlockUse));

Я думаю, что это связано с моим использованием delete [].Пожалуйста, помогите, я действительно застрял.

#include <iostream>
using namespace std;

class list{
public:
 char *value;
 int size;
 list(int s){size=s; allocmem();};
 ~list(){delete [] value;};
 list operator+(list);
private:
 void allocmem(void);
};

void list::allocmem(void){
 value=new char[size];
}

list list::operator+(list a)
{
 list t(a.size+size);
 for (int i=0; i<a.size; i++){
      t.value[i]=a.value[i];
 }
 for (int i=a.size; i<t.size; i++){
      t.value[i]=a.value[i-a.size];
 }
 return t;
}

int main ()
{
     list a(2),b(2),c(4);
     a.value[0]='a';
     b.value[0]='b';
     a.value[1]='c';
     b.value[1]='d';
     c=a+ b;
     for (int i=0; i<c.size; i++){
          cout<<c.value[i];
     }
     system("pause");
     return 0;
}

Пожалуйста, помогите!

Ответы [ 4 ]

1 голос
/ 03 декабря 2010

Первый предупреждающий знак: деструктор вашего класса выполняет некоторые действия delete, но класс не определяет конструктор копирования или оператор присваивания копии.

См. Правило трех .

Вы, вероятно, случайно делаете временные копии объектов и портите их, когда вызывается временный деструктор.

1 голос
/ 03 декабря 2010

Вам нужно определить оператор присваивания (list::operator=(list const&)) и конструктор копирования (list::list(list const&)) для вашего класса, чтобы избежать двойного удаления памяти в деструкторе. Если вы не определите эти функции, компилятор будет использовать созданные по умолчанию версии этих функций, которые по существу создают побитовую копию объекта списка. Это катастрофически, так как после копирования экземпляра вашего списка оба экземпляра будут иметь одинаковое значение указателя, что приведет к удалению дубликата.

0 голосов
/ 03 декабря 2010

Вместо того, чтобы работать со строками char* напрямую, почему бы не использовать std::string? Тогда вам не нужно беспокоиться о проблемах управления памятью (в этом случае двойное удаление из-за отсутствия реализации конструктора копирования, как отмечали другие). В самом буквальном переводе это будет что-то вроде:

class list
{
public:
 std::string value;
 int size;
 list(int s){size=s; allocmem();}
 ~list(){}
 list operator+(list);
private:
 void allocmem(void);
};


void list::allocmem(void){
 value.resize(size);
}

Обратите внимание, что почти наверняка есть лучшие реализации, использующие string более нормально (например, size может уйти). Кроме того, вы, вероятно, не должны иметь все свои атрибуты public.

0 голосов
/ 03 декабря 2010

Вам нужно сделать 2 вещи:

  1. создать конструктор копирования, который создаст собственную копию данных
  2. передать по ссылке, а не по значению.

Вы передаете по значению в operator +(). Это передаст копию объекта (не то, что вы хотите; вы хотите передать ссылку). Но поскольку вы не создали конструктор копирования, скопированный объект получает копию по умолчанию для каждого члена - теперь 2 объекта имеют одинаковый указатель. Первый удаляет его нормально, а второй объект теперь имеет недопустимый указатель.

...