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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.10.2014, 16:52   #1
Lifeda92
Пользователь
 
Регистрация: 15.08.2012
Сообщений: 39
Сообщение Class list (вопрос по деструктору)

Здравствуйте, хочу узнать правильно ли происходит освобождение памяти (все ли освобождается, то что было выделено) с помощью деструктора.
Спасибо.

Код:
/* main.cpp */

#include "list.h"
#include <iostream>

using namespace std;

int  main() {
	list l1(0);
	for (int i = 1; i <= 9; i++)
		l1.add(i);

	cout << l1.length() << endl;

	return 0;
}
Код:
/* list.h */

#ifndef LIST_H_
#define LIST_H_

class list {
	int *Value;
	list *NextValue = 0;
public:
	list(const int&);
	~list();
//-------------------------
	void add(const int&);
	int length();
};

#endif
Код:
/* list.cpp */

#include "list.h"

list::list(const int &val) {
	Value = new int(val);
}

list::~list() {
	if (NextValue != 0) delete NextValue;
	delete Value;	
}

void list::add(const int &val) {
	list *current = this;
	while (current -> NextValue != 0)
		current = current -> NextValue;
	current -> NextValue = new list(val);
}

int list::length() {
	int count = 1;
	for (list *current = this; (current -> NextValue) != 0; count++)
		current = current -> NextValue;
	return count;
}
Lifeda92 вне форума Ответить с цитированием
Старый 15.10.2014, 17:03   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

пойдёт для сельской местности
pu4koff вне форума Ответить с цитированием
Старый 15.10.2014, 20:16   #3
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Lifeda92 Посмотреть сообщение
Здравствуйте, хочу узнать правильно ли происходит освобождение памяти (все ли освобождается, то что было выделено) с помощью деструктора.
Спасибо.
1. Диструктор сломается в многопоточной среде (впрочем в многопоточной среде ваш код скорее всего поломается ещё раньше).

2. В диструкторе стоит ненужная проверка на нуль.
Её можно убрать, что б не мельтешила. Но если не убирать, компилятор скорее всего самостоятельно её выпилит.

3. Если у вас используются сырые указатели в качестве мемберов класса, значит вам нужны явные конструктор копии, и оператор=

В противном случае ваш код сломается в диструкторе, если будет созданно более одного экземпляра класса через конструктор копии, или оператор=

Пример:

http://rextester.com/PMJ8913





Код:
class list {
	int *Value;
	list *NextValue = 0;
public:
	list(const int&);
	~list();
//-------------------------
	void add(const int&);
	int length();
};


list::list(const int &val) {
	Value = new int(val);
}

list::~list() {
	if (NextValue != 0) delete NextValue;
	delete Value;	
}

void list::add(const int &val) {
	list *current = this;
	while (current -> NextValue != 0)
		current = current -> NextValue;
	current -> NextValue = new list(val);
}

int list::length() {
	int count = 1;
	for (list *current = this; (current -> NextValue) != 0; count++)
		current = current -> NextValue;
	return count;
}



#include <iostream>
using namespace std;

int  main() {
	list l1(0);
	for (int i = 1; i <= 9; i++)
		l1.add(i);

	cout << "l1 length: " << l1.length() << endl;
    
    
    list l2 = l1;
    
    cout << "l2 length: " << l2.length() << endl;

	return 0;
}
_Bers вне форума Ответить с цитированием
Старый 16.10.2014, 15:59   #4
Lifeda92
Пользователь
 
Регистрация: 15.08.2012
Сообщений: 39
По умолчанию

if (NextValue != 0) delete NextValue;
Это как бы проверка указывает ли NextValue на еще 1 объект типа list, то есть если не указывает (равен 0), то это конец цепочки всех объектов list (дальше уже нету объектов типа list) и смысла делать delete NextValue нету.

Я могу не делать эту проверку, компилятор сам поймет то что нечего освобождать по 0 адресу? Я правильно понимаю?
Спасибо.

В противном случае ваш код сломается в диструкторе, если будет созданно более одного экземпляра класса через конструктор копии, или оператор=

Тут будет - double free, я просто сделал пока что для 1 экземпляра) (в смысле конструктор копий и перегрузку оператора= пока не задевал, и не планировал что бы ее кто-то другой задевал. Про потоки мне еще пока рано думать (не дорос))))))).

Последний раз редактировалось Stilet; 16.10.2014 в 21:28.
Lifeda92 вне форума Ответить с цитированием
Старый 16.10.2014, 16:51   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
Я могу не делать эту проверку, компилятор сам поймет то что нечего освобождать по 0 адресу? Я правильно понимаю?
Просто delete ptr (ptr = NULL) вполне безопасно
Цитата:
A pointer to the memory block to be released, type-casted to a void*.
If this is a null-pointer, the function does nothing.
p51x вне форума Ответить с цитированием
Старый 16.10.2014, 16:54   #6
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Компилятор сам втихаря конструктор копии делает (который тупо копирует члены объекта), если программист свой вариант не сделал.
Кстати, зачем value указателем сделан?
pu4koff вне форума Ответить с цитированием
Старый 16.10.2014, 17:06   #7
Lifeda92
Пользователь
 
Регистрация: 15.08.2012
Сообщений: 39
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Компилятор сам втихаря конструктор копии делает (который тупо копирует члены объекта), если программист свой вариант не сделал.
Кстати, зачем value указателем сделан?
Указатель типа int класса list (*Value) указывает по адресу объекта типа int (выделенного динамически в конструкторе класса list).
Lifeda92 вне форума Ответить с цитированием
Старый 16.10.2014, 20:43   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Lifeda92 Посмотреть сообщение
if (NextValue != 0) delete NextValue;
Это как бы проверка указывает ли NextValue на еще 1 объект типа list, то есть если не указывает (равен 0), то это конец цепочки всех объектов list (дальше уже нету объектов типа list) и смысла делать delete NextValue нету.

Я могу не делать эту проверку, компилятор сам поймет то что нечего освобождать по 0 адресу? Я правильно понимаю?
Да. Грубо говоря внутри delete стоит точно такая же проверка.
Если указатель нулевой, удаления не происходит. Он просто игнорируется.

Поэтому, нет никакого смысла ставить ещё одну проверку.
_Bers вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по STL. template <class Iterator> Smitt&Wesson C++ Builder 8 05.06.2014 10:03
Делфи: выдает ошибку "Project raised exception class EstringListError wits message 'list index out of bounds (-1)' Катерина19 Помощь студентам 1 15.04.2014 12:15
Не удается добавить сортировку в List Control: Error 64 error C2504: 'CHeaderCtrl' : base class undefined vaan.sk Общие вопросы C/C++ 2 29.11.2012 09:48
project raised exception class estringlisterror with message list index out of bounds obsession Общие вопросы Delphi 23 09.05.2011 01:31
ошибка raized exception class EListError with message 'List index out of bounds(1)'.Process stopped SGRaptor Софт 0 22.05.2010 19:12