I have a function that returns an object on the stack. I need to save the result in dynamic memory. Can this be done without copying? The function cannot be changed, the object is very large, move- semantics is not provided by the library. I tried byte-by-copy to copy an object, but you cannot use it after exiting a function. The destructor destroys the data necessary for working with the object.

  • 2
    Well, allocate in the function the returned object immediately on the heap. If the function cannot be changed, there is no way out. - VladD
  • one
    And what does it mean “to use it after exiting a function is impossible? destructor destroys neoodimy to work with the object data? That is, the function returns a dead object to you? Well, then this function in any case can not be used. - VladD 5:09
  • Most likely there is no way out. The returned object works as expected before the destructor is called. I naively tried to copy the resulting object by-byte, but it’s understandable that after calling the destructor it destroys the sub-objects selected in the heap and it turns out a dead copy. - Tvyxen
  • You give a simplified example, but something very vaguely turns out you have to explain what is and what is needed. The feeling that this object function does NOT return to you ... - Harry
  • Give the existing code, since you have it. And even the function signature is not clear. - αλεχολυτ

1 answer 1

Firstly, in C ++ there is an RVO - optimization of the return value, when an object seems to be created on the stack (judging by the program code), but in fact, no copying occurs on return:

std::string test() { std::string ret="qqq"; //... return ret; } 

If this does not suit you, use new () and create an object on the heap.

If you really want to allocate an object on the stack, you can take the memory from the stack of the calling function using alloca (), and then place the object in it using placement-new ().

 #include <iostream> #include <cassert> using namespace std; class Foo { public: Foo() { cout << "construct" << endl; } ~Foo() { cout << "destruct" << endl; } }; Foo* user(void* mem) { cout << " create" << endl; return new(mem) Foo(); } int main() { void* mem=alloca(sizeof(Foo)); assert(mem); Foo* foo=user(mem); cerr << "delete" << endl; foo->~Foo(); // нужно ЯВНО вызвать деструктор //а вот память, выделенную alloca, освобождать НЕ НУЖНО. return 0; } 

IDEONE

  • It is not clear, why not initially allocate memory dynamically instead of using a non-standard function? - Vlad from Moscow
  • Allocation of dynamic memory is expensive - you can accidentally switch the context. This is not quite clean, from the point of view of the standard trick, allows you to sit on two chairs - to create an object on the stack, without wasting time walking around the memory in a heap, and not to make additional copying with destruction. And do not even make a move (!). Decent compilers in this place do RVO, I show how to create an RVO by brute force. - gbg