Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.02.2012, 09:29   #1
alexey_kip
Форумчанин
 
Регистрация: 19.11.2011
Сообщений: 198
Печаль Ошибка при очистке памяти

Всё просто: в классе создаю конструктор, деструктор, указатель на тип char и перегружаю операцию "больше".
В main'e создаю 2 переменных типа "клас" и сравниваю их между собой.
При сравнении вызывается деструктор и уничтожает вторую переменную, т.е. после сравнения пользоваться ей уже не получится, т.к. там будет мусор. Ну и соответственно на выходе из программы деструктор вызовется два раза, из-за чего вылетит ошибка (при выполнении) _BLOCK_TYPE_IS_VALID...
Кто знает как от этой ошибки избавиться?

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
"2.h"
class c
{
public:
char *t;
c();
bool operator >(c);
~c();
};

c::c()
{
t=new char;
*t='t';
}

bool c:perator >(c v)
{
if (*t>*v.t) return 1;
else return 0;
}

c::~c()
{
delete t;
}


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
"1.cpp"
#include "2.h"
void main()
{
c t,u;
bool b=t>u;
}
alexey_kip вне форума Ответить с цитированием
Старый 12.02.2012, 10:33   #2
alexey_kip
Форумчанин
 
Регистрация: 19.11.2011
Сообщений: 198
По умолчанию

Тоже самое не только при перегрузке оператора, а вообще при вызове любого метода (созданного в классе), которое возвращает значение не void
alexey_kip вне форума Ответить с цитированием
Старый 12.02.2012, 11:21   #3
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от alexey_kip Посмотреть сообщение
Всё просто: в классе создаю конструктор, деструктор, указатель на тип char и перегружаю операцию "больше".
В main'e создаю 2 переменных типа "клас" и сравниваю их между собой.
При сравнении вызывается деструктор и уничтожает вторую переменную, т.е. после сравнения пользоваться ей уже не получится, т.к. там будет мусор. Ну и соответственно на выходе из программы деструктор вызовется два раза, из-за чего вылетит ошибка (при выполнении) _BLOCK_TYPE_IS_VALID...
Кто знает как от этой ошибки избавиться?

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
"2.h"
class c
{
public:
char *t;
c();
bool operator >(c);
~c();
};

c::c()
{
t=new char;
*t='t';
}

bool c:perator >(c v)
{
if (*t>*v.t) return 1;
else return 0;
}

c::~c()
{
delete t;
}


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
"1.cpp"
#include "2.h"
void main()
{
c t,u;
bool b=t>u;
}
Проблема связана с тем, что вы не определили конструктор копирования. Когда программист не объявляет конструктор копирования, то его неявно объявляет компилятор. Этот конструктор копирования осуществляет почленное копирование данных из существующего объекта в создаваемый.

Вы объявили оператор сравнения bool operator >(c);, в который объект передается по значению. Это означает, что когда вы пишите выражение bool b=t>u;, то создается временный объект с помощью конструктора копирования из объекта u. В этом случае член c::t в обоих объектах указывает на один и тот же адрес. При завершении работы оператора сравнения временный объект удаляется и вызывается его деструктор, который в свою очередь удаляет память, на которую указывает член временного объекта c::t , Затем когда программа завершается, удаляется также объект u, и его деструктор уже по второму разу пытается удалить память, на которую указывает его u.t. Естественно возникает аварийное завершение.

То есть вам помимо конструктора по умолчанию нужно было еще явно определить конструктор копирования

c::c( const c &rhs ) : t( new char( rhs.t ) ) {}

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

Код:
class c
{
   // другие объявления опущены
   bool operator >( const c &rhs ) const;
};

bool c::operator >( const c &rhs ) const
{
   return ( t > rhs.t );
}
Вам также надо объявить свой оператор присваивания, так как в противном случае может возникнуть такая же ошибка, если вы будете примваивать объякты вашего класса друг друггу.
Функция main в С++ объявляется как int main()
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 12.02.2012 в 11:29.
Сыроежка вне форума Ответить с цитированием
Старый 12.02.2012, 11:55   #4
alexey_kip
Форумчанин
 
Регистрация: 19.11.2011
Сообщений: 198
По умолчанию

Спасибо, учту
alexey_kip вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка чтения памяти при посылки дублирующей команды Close Вспомогательной Форме (Form2) deryt Общие вопросы Delphi 4 09.01.2012 22:14
ошибка Edit при очистке значения Backspace-ом voverrr Общие вопросы Delphi 14 08.02.2011 09:27
Ошибка доступа при выделении памяти в чужом процессе Neoteric Общие вопросы Delphi 21 06.12.2010 16:50
Ошибка доступа памяти, при работе с принятой строкой. Zeraim Работа с сетью в Delphi 11 26.01.2010 01:11
Ошибка при очистке динамического массива. S_Yevgeniy Помощь студентам 4 24.12.2009 18:45