Возможные проблемы во время выполнения, возникающие при перемещении временного объекта в объект, выделенный в куче?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Возможные проблемы во время выполнения, возникающие при перемещении временного объекта в объект, выделенный в куче?

Сообщение Anonymous »

Это очень запутанный пример, который, вероятно, встречается редко, но я столкнулся с проблемами при выполнении следующих действий:

class MyClass{
public:
SubClass1 object1; //has pointers/smart-pointers to objects that have pointers to SubClass2
SubClass2* object2; //has pointers/smart-pointers to objects that have pointers/smart-pointers to SubClass1
MyClass(){ object2 = new SubClass2(&object1); }; //SubClass2 constructor establishes the relationship between object1 and object2 pointed-to-objects.
};
/*....*/
MyClass* ptr = new MyClass(std::move(MyClass()));


Я обнаружил, что некоторые указатели внутри объекта2 недействительны. Я хотел бы поделиться определениями SubClass1 и SubClass2, но, к сожалению, мне не разрешено делиться этим кодом.

Мой вопрос: существуют ли определенные контрольные списки, которые объект класса должно удовлетворять, чтобы предотвратить проблемы при перемещении временного объекта в новый объект, выделенный в куче?
Есть ли какие-либо способы заранее узнать, завершится ли операция перемещения из неудачно?

Первоначальная проблема возникла из-за ошибочного написания:

std::shared_ptr ptr = std::make_shared(MyClass());


при изменении всех моих экземпляров Shared_ptr на создание с помощью make_shared вместо new. В итоге я сузил проблему до необработанных указателей, std::move и временной ссылки на rvalue.

При выполнении:

std::shared_ptr ptr = std::make_shared();


все работало отлично.

Любопытно, что следующих проблем не возникло:

MyClass stack_obj{};
MyClass* ptr = new MyClass(std::move(stack_obj));


Кажется, есть что-то особенное в перемещении временного объекта в кучу?

Я также обнаружил, что если бы я изменил объект1, чтобы он стал указателем на Подкласс1, у меня тоже не было бы никаких проблем.
т.е.

class MyClass{
public:
SubClass1* object1;
SubClass2* object2;
MyClass(){ object1 = new SubClass1(); object2 = new SubClass2(object1); };
};
/*....*/
MyClass* ptr = new MyClass(std::move(MyClass())); //worked fine


Единственная проблема, которую я мог себе представить, заключалась в том, что объект 1 создавался в стеке для временного объекта MyClass(), а затем проблема возникла из-за перемещения объекта 1 из локального стек в кучу во время выделения указателя.

Для завершения, вот другие способы, с помощью которых я смог воспроизвести ту же проблему для исходного класса:

template
std::shared_ptr make_shared_test(Args&& ... args)
{
return std::shared_ptr(new MyClass(std::forward(args)...));
}

MyClass&& forward_test(MyClass&& param){
return static_cast(param);
}

/*....*/
MyClass* obj1(new MyClass(std::move(MyClass())));
std::shared_ptr obj2 = make_shared_test(MyClass());
std::shared_ptr obj3 = std::shared_ptr(new MyClass(forward_test(MyClass())));
std::shared_ptr obj4 = std::shared_ptr(new MyClass(std::move(MyClass())));
std::shared_ptr obj5(new MyClass(std::move(MyClass())));


Подробнее здесь: https://stackoverflow.com/questions/507 ... eap-alloca
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»