powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / проблемы с последовательностью вызовов десктрукторов
22 сообщений из 22, страница 1 из 1
проблемы с последовательностью вызовов десктрукторов
    #33330608
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу поразмышлять над такой проблемой. Есть класс, реализующий очередь в самом общем виде, т.е. подходящий для любых типов элементов, образующих очередь. Также есть, например, класс 'C'-строк, содержащий указатель на строку. Для этого указателя память выделяется динамически в зависимости от длины строки. Проблема такова: в клиентском файле, реализующем работу с очередью из строк, при создании объектов-строк и помещении их в очередь при завершении программы, необходим сначала вызов деструктора для класса строк, а затем уже вызов деструктор для самой очереди. При не соблюдении данной очередности вызовов деструкторов возникает ошибка во время исполнения программы. Как можно решить эту проблемму, не прибегая к наследованию и другим усложнениям.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33330661
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В чем именно проблема?
Есть контейнер (пусть очередь в данном случае, хотя не важно)
Вполне естественно, если при уничтожении сначала отработают деструкторы для элементов контейнера, а потом деструктор самого контейнера. Так IMHO и должно работаь. В чем может быть засада? Или я чего-то недопонял в вопросе?
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33330990
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
redskinВ чем именно проблема?
? Или я чего-то недопонял в вопросе?

Напишу конкретней:
int main()

{

создание объекта очереди;
заполнение очереди объектами-строками;

} - здесь программа заканчивается; очередь уничтожается, не успев высвободить выделенную память для объектов-строк. Т.е. деструктор для строк не вызывается перед деструктором для очереди. (деструктор объектом не вызовешь!).
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331006
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
geltr redskinВ чем именно проблема?
? Или я чего-то недопонял в вопросе?

Напишу конкретней:
int main()

{

создание объекта очереди;
заполнение очереди объектами-строками;

} - здесь программа заканчивается; очередь уничтожается, не успев высвободить выделенную память для объектов-строк. Т.е. деструктор для строк не вызывается перед деструктором для очереди. (деструктор объектом не вызовешь!).
std::vector< std::string > корректно все делает. Что мешает сделать так же?
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331027
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей ИльичЧто мешает сделать так же?

Просто необходимо написать самому очередь из C-строк без использования "встроенных" классов С++. Т.е. написать класс 'очередь' и класс 'строка', являющийся элементами очереди. Программа работает, но выдает ошибку во время выполнения.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331034
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331038
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В C нет строк
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331056
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluk (Kazan)В C нет строк
Я знаю, поэтому и пишу "C-строки", что означает массив char'ов, завершенный '\0'.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331085
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluk (Kazan) Если речь идет об указателях на объекты в очереди
Слишком сложно. Мне необходима самая простая реализация без шаблонов и без _ptr, потому что я пока их просто не знаю.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331174
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что-то вы не то рассказываете! Приведите код
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331209
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну дык и вызывай delete явно, что мешает ???
А вобче, учи C++
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331387
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
geltrКак можно решить эту проблемму, не прибегая к наследованию и другим усложнениям.
В конце работы пробежать в цикле по всей очереди и освободить память выделеную для каждого из элементов. Все.
Кстати, то что называешь "С-строки" обычно называется ASCIIz строки :)
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331498
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
funikovyuriчто-то вы не то рассказываете! Приведите код

Так и быть. Привожу код программы.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331541
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
geltr funikovyuriчто-то вы не то рассказываете! Приведите код

Так и быть. Привожу код программы.


Эээ.... так нельзя.
Такой класс строки, который у вас написан, никуда не годится.
Я даже не стал смотреть на реализацию очереди, поэтму не скажу точную причину ваших граблей, но помедитируйте вот этим примером: (класс C_string - из вашего исходника)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
#include <iostream>

using namespace std;

class C_string
{
private:
	char * pstr;
public:
	C_string(char * ps = "none");
	~C_string() { delete [] pstr; }
	char * str() { return pstr; }
};

C_string::C_string(char * ps)
{
	pstr = new char[strlen(ps) +  1 ];
	strcpy(pstr,ps);
}

void f(C_string c_str)
{
	cout << c_str.str();
}

int main(int argc, char *argv[])
{

	{
		C_string c("abc");
		f(c);
	}

	return  0 ;
}

Тестовая "нехорошая" функция моя.
И не говорите, что у вас никогда такого не случится и что ваш класс все будут использовать "как надо". :-))

p.s. кстати, как раз такую задачку (почему все компилируется, но валится) дают в нашем отделе на собеседовании. Азы С++.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331578
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p.s. Hint: добавьте в описание класса (из целого примера, который вы прикрепили к сообщению) такую строчку:

Код: plaintext
1.
2.
public:
  C_string& operator=(const C_string& str){cout << "operator =\n"; return *this;} ;

Запустите на выполнение и посмотрите на вывод.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33331964
Kornjushin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
p.s. кстати, как раз такую задачку (почему все компилируется, но валится) дают в нашем отделе на собеседовании. Азы С++.

А можно не сильно сведущим ответить что не так с этим классом, глюк на лицо, но что не так не пойму
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33332039
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kornjushin
А можно не сильно сведущим ответить что не так с этим классом, глюк на лицо, но что не так не пойму

Один из членов класса C_string - указатель pstr. На конструкторе выделяется память, на деструкторе освобождается, вроде бы все в порядке. Но для C_string не опеределены ни конструктор копирования, ни оператор присваивания. В этом случае компилятор генерирует их самостоятельно и в них выполняется обычное побитовое копирование один в один.

Теперь при попытке присвоить один объект класса C_string другому или передать его по значению в функцию, будет создана абсолютно идентичная копия. Адрес в pstr тоже будет одинаковым. Когда объектам придет время умирать, будет попытка дважды освободить одну и ту же область памяти и привет.

Выход: либо нормально реализовать копирующий конструктор и оператор присваивания, либо явно запретить копирование и передачу объектов по значению, поместив объявления этих методов в private и не определяя их.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33332235
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это как-то странно. Если очередь ответствена за удаление своих элементов, то она должна сначала удалить все элементы очереди (стороки) а потом уже себя. По другому и быть не может, если не предпринимать дополнительных усилий.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33332348
Kornjushin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А показать как это реализовать не затруднит?
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33332488
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KornjushinА показать как это реализовать не затруднит?

Явный запрет копирования и передачи по значению:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
...
class C_string
{
private:
	C_string(const C_string&);
	C_string& operator=(const C_string&);

...


При этом сами методы не определяем. Если мы потом где-нибудь попробуем создать копию объекта, то компилер грязно выругается. А можно их перенести таки в public и реализовать, например так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
#include <iostream>
using namespace std;

class C_string
{
private:
	char * pstr;

public:
	C_string(char * ps = "none");
	~C_string() { delete [] pstr; }

	C_string(const C_string&);
	C_string& operator=(const C_string&);

	char * str() const { return pstr; };
};

C_string::C_string(char * ps)
{
	pstr = new char[strlen(ps) +  1 ];
	strcpy(pstr,ps);
}

C_string::C_string(const C_string& c)
{
	pstr = new char[strlen(c.str()) +  1 ];
	strcpy(pstr, c.str());
}
C_string& C_string::operator=(const C_string& c)
{
	if(this != &c)
	{
		delete[] pstr;
		pstr = new char[strlen(c.str()) +  1 ];
		strcpy(pstr, c.str());
	}
	return *this;
}

void f(C_string c_str)
{
	cout << c_str.str() << endl;;
}

int main()
{
	C_string c1, c2, c3("abc");
	c1 = c3;
	f(c1);
	f(c2);
	f(c3);

	return  0 ;
}

Вообще эта тема обстоятельно разжевана во многих хороших книгах по С++ (Эккель, Майерс и пр.)
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33333494
geltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо за активное обсуждение, особенно redskin'у.
...
Рейтинг: 0 / 0
проблемы с последовательностью вызовов десктрукторов
    #33333632
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
geltrВсем спасибо за активное обсуждение....

добавлю, что на мой взгляд Вам будет интересно почитать Джэфа Элджэра...

в этой помойке найдёте электронный вариант...

С++ . Библиотека программиста. Автор: Джефф Элджер. 259 стр., РУС, PDF.


с уважением
(круглый)
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / проблемы с последовательностью вызовов десктрукторов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]