Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему падает этот код / 6 сообщений из 6, страница 1 из 1
07.04.2013, 12:35
    #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
07.04.2013, 12:37
    #38215974
Почему падает этот код
deleted выдается дважды. то есть объект, созданный один раз, удаляется дважды. спрашивается, какого хрена.
...
Рейтинг: 0 / 0
07.04.2013, 13:21
    #38216019
OoCc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему падает этот код
shared_ptr быдлокодер,

используй enable_shared_from_this<> shared_from_this()
...
Рейтинг: 0 / 0
07.04.2013, 13:37
    #38216034
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему падает этот код
Как написано так и происходит.
...
Рейтинг: 0 / 0
07.04.2013, 16:55
    #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
08.04.2013, 00:36
    #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
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему падает этот код / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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