Passing STL vector wrapped in shared_ptr

I'm wondering about a situation where I'm trying to return a vector from DLL to .exe app. Compilers and settings for DLL and .exe app are the same. I know that passing STL vector through DLL boundaries might cause memory errors in case of alloc/dealloc memory.

What about the case when returning a vector wrapped by shared_ptr? Is this memory safe?

Little example:

exported DLL method:

__declspec(dllexport) std::shared_ptr<std::vector<MyObject>> MyDLL::myMethod()
{
    //Create object
    MyObject obj;
    std::vector<MyObject> myVector;
    myVector.push_back(obj);

    //Create wrapper
    std::shared_ptr<std::vector<MyObject>> spvObject = std::make_shared<std::vector<MyObject>>(myVector);

    return spvObject;
}

Get this data on .exe side:

MyDll dll;
std::shared_ptr<std::vector<MyObject>> objFromDll = dll.myMethod();

What will happen when pointer from .exe app will go out of scope? Will there be a memory error in case of deleting heap from DLL?

3 answers

  • answered 2018-01-11 19:51 SoronelHaetir

    So long as the EXE and DLL agree on the allocator being used passing objects across the boundary is okay, that is however a very big "if". It would be violated, for example, by re-building the EXE with a new compiler version but not re-building the DLL.

    shared_ptr really doesn't change this, it merely ensures that the object will be deleted when no longer referenced, it has no bearing on what allocator will actually be used.

  • answered 2018-01-11 19:51 Deduplicator

    Well, the std::shared_ptr itself is safe, because it uses type-erasure on its allocator.

    What isn't safe is the std::vector it owns, as that uses std::allocator directly, unless your EXE and your DLL agree on the definition of the latter, for example because they use the same shared runtime-library.
    Wrapping it in a std::shared_ptr hasn't really changed anything.

  • answered 2018-01-11 19:51 Alexander Lelyakin

    std::shared_ptr constructor can accept a 'Deleter', it will be stored inside the control block. Maybe appropriate deleter function in DLL will help with EXE/DLL boundaries?

    BTW: std::vector can use custom allocator and it also can be customized to work in dll or exe address space.