powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему падает этот код
6 сообщений из 6, страница 1 из 1
Почему падает этот код
    #38215970
Код: 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.
class myc;

void test(shared_ptr<myc> obj)
{
	
}

class myc {
public:
	myc()
	{
		cout << "created";
		test(shared_ptr<myc>(this));//из-за этой строки в debug-режиме ошибка Assert в проверке валидности блока памяти
	}

	~myc()
	{
		cout << "deleted";
	}
};



int _tmain(int argc, _TCHAR* argv[])
{
	shared_ptr<myc> obj(new myc());
	return 0;
}
...
Рейтинг: 0 / 0
Почему падает этот код
    #38215974
deleted выдается дважды. то есть объект, созданный один раз, удаляется дважды. спрашивается, какого хрена.
...
Рейтинг: 0 / 0
Почему падает этот код
    #38216019
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shared_ptr быдлокодер,

используй enable_shared_from_this<> shared_from_this()
...
Рейтинг: 0 / 0
Почему падает этот код
    #38216034
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как написано так и происходит.
...
Рейтинг: 0 / 0
Почему падает этот код
    #38216171
Нафиг тут шаред поинтер? Используй ссылку:
Код: 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.
class myc;

void test(myc &obj)
{
	
}

class myc {
public:
	myc()
	{
		cout << "created";
		test(*this);//из-за этой строки в debug-режиме ошибка Assert в проверке валидности блока памяти
	}

	~myc()
	{
		cout << "deleted";
	}
};



int _tmain(int argc, _TCHAR* argv[])
{
	shared_ptr<myc> obj(new myc());
	return 0;
}
...
Рейтинг: 0 / 0
Почему падает этот код
    #38216439
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рассмотрим, как это работает во времени:
Код: plaintext
1.
	shared_ptr<myc> obj(new myc());



выделяется память с помощью operator new

инициализируется объект класса myc, вызывается его конструктор.


Код: plaintext
1.
2.
3.
4.
5.
	myc::myc()
	{
		cout << "created";
		test(shared_ptr<myc>(this));//из-за этой строки в debug-режиме ошибка Assert в проверке валидности блока памяти
	}




выводится строка "created"

для вызова функции test создаётся временный объект shared_ptr<myc>, инициализируемый this. Так как ещё нет ни одного shared_ptr<myc>, ссылающегося на данный объект, счёткик использования объекта равен 1.

для вызова функции test создаётся копия временного объекта класса shared_ptr<myc> с указателем на наш создаваемый объект. Счётчик испльзования объекта будет уже 2.

Код: plaintext
1.
2.
3.
void test(shared_ptr<myc> obj)
{
}




поскольку функция test пустая, мы тут же выходим из неё и при этом уничтожается объект-параметр shared_ptr<myc> obj, счётчик испльзования объекта уменьшается с 2 до 1.

Возвращаемся к строке
Код: plaintext
1.
		test(shared_ptr<myc>(this));//из-за этой строки в debug-режиме ошибка Assert в проверке валидности блока памяти




функция test успешно вызвана, после её вызова есть точка следования по концу выражения (';') и временный объект shared_ptr<myc>(this) уничтожается. При этом счётчик использования, который был 1, становится 0, и объект this удаляется.
Это уже нехорошо, поскольку происходит это в конструкторе, возможно, до завершения полной инициализации данного объекта.

Завершается исполнение конструктора. По адресу this уже лежит невалидный, удалённый объект.

Управления возвращается на строку:

Код: plaintext
1.
shared_ptr<myc> obj(new myc());




Происходит создание автоматического объекта shared_ptr<myc> и инициализация его адресом уже удалённого объекта. счётчик использования = 1.

программа выполняется до конца main, shared_ptr<myc> obj выходит из своего скоупа, срабатывает деструктор shared_ptr<myc> , счётчик переходит с 1 на 0, производится попытка удаления объекта, но его адрес уже невалидный.

Вывод простой -- наверное, использование в конструкторе shared_ptr -- это плохая идея, потому что вся идея shared_ptr основана на концепции владения объектом, а очевидно, что объект сам собой владеть не может.

Замечу также, что наличие в конструкторе класса myc выражения

Код: plaintext
1.
shared_ptr<myc>(this)



подразумевает, что объекты класса myc могут создаваться только одним способом -- в хипе. Это очень плохо (хотя стандарт языка это не запрещает), потому что в C++ объекты могут быть четырёх разных способов размещения, и все эти способы равноправны. Не дело конструктора управлять этим. И это ещё одна причина, почему shared_ptr и им подобные плохо использовать в конструкторах.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему падает этот код
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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