ошибка удаления деструктора c при выделении

#c #destructor

Вопрос:

В приведенном ниже коде c во время вызова деструктора происходит сбой с приведенной ниже ошибкой.

Если это сообщение напечатано, то, по крайней мере, программа еще не вышла из строя! Но вы, возможно, захотите распечатать и другие диагностические сообщения. Коды DSCodes(16782,0x1000efe00) malloc: *** ошибка для объекта 0x10742e2f0: освобождаемый указатель не был выделен Коды DSCodes(16782,0x1000efe00) malloc: *** установите точку останова в malloc_error_break для отладки

Может кто-нибудь указать мне на ошибку в деструкторе

 class Pair {
 public:
  int *pa,*pb;
   Pair(int, int);
   Pair(const Pair amp;);
  ~Pair();
 };
 
Pair::Pair(int p1, int p2)
{
    this->pa = new int;
    this->pb = new int;
    *pa = p1;
    *pb = p2;
}
Pair::Pair(const Pair amp;obj)
{
    this->pa= new int;
    this->pb = new int;
    this->pa = obj.pa;
    this->pb = obj.pb;
}
 
Pair::~Pair()
{
    if(pa)
        delete (pa);
    if(pb)
        delete(pb);
}
 /* Here is a main() function you can use
  * to check your implementation of the
  * class Pair member functions.
  */
  
int main() {
  Pair p(15,16);
  Pair q(p);
  Pair *hp = new Pair(23,42);
  delete hp;
  
  std::cout << "If this message is printed,"
    << " at least the program hasn't crashed yet!n"
    << "But you may want to print other diagnostic messages too." << std::endl;
  return 0;
}
 

Комментарии:

1. Пожалуйста, напомните себе о разнице между ptr = 0 и *ptr = 0

2. Почему вы используете динамическое распределение для двух int ? Указатели на int занимают по крайней мере столько же места, сколько и сами int, и это без дополнительных затрат на выделение памяти. Если у вас нет очень веских причин использовать указатели, int a, b это должен быть правильный путь.

3. Это не решает вопроса, но этот код можно написать гораздо проще. Все эти this-> s-просто шум; компилятор знает, что это за члены. И вы можете инициализировать при выделении. Так pa = new int(p1); . И, действительно, это должно быть в списке инициализаторов: Pair::Pair(int p1, int p2 : pa(new int(p1), pb(new int(p2) {} . И, наконец, вам не нужно проверять наличие нулевого указателя перед удалением указателя. Так Pair::~Pair() { delete pa; delete pb; } .

Ответ №1:

В вашей паре::Пара(const Pair amp;obj) вы фактически копируете указатель, который впоследствии дважды уничтожается. Вместо этого вы хотите скопировать содержимое указателя (см. Конструктор Pair::Pair(int p1, int p2)).

Комментарии:

1. Спасибо, изменив конструктор копирования, как показано ниже, исправил это.Pair::Pair(const Pair amp;obj) { this->pa= новый int(*obj.pa); это->>pb = новый int(*obj.pb); }

Ответ №2:

Проблема в том, что ваш конструктор копирования присваивает p1 и p2 другому объекту текущий объект ( q содержит то же p1 самое и p2 это p ). Поэтому в конце программы q деструктор и p деструктор пытаются удалить оба одинаковых указателя.

В конструкторе копирования вы должны копировать целые числа, а не только копировать указатель.