DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

+ Reply to Thread
Results 1 to 8 of 8
  1. #1
    Sorin Gherman Guest

    Returning a vector<int> from a dll


    I have a method exported from a VC++ dll that needs to create a vector<int>
    and return it.

    Allocating it on the heap with new creates problem for the program using
    the dll: deallocation may fail if the dll and the program are not compiled
    with the same run-time library.

    So we decided to return it by value in order to avoid alocation/deallocation
    problems.

    In dll I have:

    vector<int> createList()
    {
    vector<int> list;
    ... //populate the list
    return list;
    }

    And in the program using the dll:

    ...
    {
    vector<int> list = createList();
    ...
    } // --> when "list" exits out of scope here, an Access Violation occurs!
    WHY??? Isn't the local object destroyed here? Why a memory conflict with
    the dll??

    Thanks in advance,
    Sorin Gherman

  2. #2
    Danny Kalev Guest

    Re: Returning a vector<int> from a dll



    Sorin Gherman wrote:
    >
    > I have a method exported from a VC++ dll that needs to create a vector<int>
    > and return it.
    >
    > Allocating it on the heap with new creates problem for the program using
    > the dll: deallocation may fail if the dll and the program are not compiled
    > with the same run-time library.
    >
    > So we decided to return it by value in order to avoid alocation/deallocation
    > problems.
    >
    > In dll I have:
    >
    > vector<int> createList()
    > {
    > vector<int> list;
    > ... //populate the list
    > return list;
    > }
    >
    > And in the program using the dll:
    >
    > ..
    > {
    > vector<int> list = createList();
    > ...
    > } // --> when "list" exits out of scope here, an Access Violation occurs!
    > WHY???


    the problem is that the list's elements reside on heap memory that was
    allocated inside the dll, and now they are deleted in a different
    context (i.e., the application itself). In other words, you simply
    transferred the problem of incompatible runtime libraries from the
    allocation stage to the destruction.

    Danny Kalev

    "The ANSI/ISO C++ Professional Programmer's Handbook"
    http://www1.fatbrain.com/asp/bookinf...sbn=0789720221

  3. #3
    Sorin Gherman Guest

    Re: Returning a vector<int> from a dll


    Danny Kalev <dannykk@inter.net.il> wrote:
    >
    >
    >Sorin Gherman wrote:

    ...
    >> In dll I have:
    >>
    >> vector<int> createList()
    >> {
    >> vector<int> list;
    >> ... //populate the list
    >> return list;
    >> }
    >>
    >> And in the program using the dll:
    >>
    >> ..
    >> {
    >> vector<int> list = createList();
    >> ...
    >> } // --> when "list" exits out of scope here, an Access Violation occurs!
    >> WHY???

    >
    >the problem is that the list's elements reside on heap memory that was
    >allocated inside the dll, and now they are deleted in a different
    >context (i.e., the application itself). In other words, you simply
    >transferred the problem of incompatible runtime libraries from the
    >allocation stage to the destruction.
    >
    >Danny Kalev


    1) Why are "list"'s element the ones allocated inside the dll? When vector<int>
    's copy-constructor is called, isn't the allocation for list being done in
    the main program and just _copying_ the content of the one allocated inside
    the dll?

    2) Is it the particular way that VC 6.0 implemented vector that causes this
    problem or is this according to STL's standard specs? Do you know if using
    Borland C++ would cause the same problem?

    3) How to solve the problem otherway than returning a pointer to a dynamically
    allocated vector<int> and later delete it with another dll function, deleteVector(
    vector<int> * ), since passing by value does not work ?

    Thanks for your answer,
    Sorin Gherman

  4. #4
    Wayne Mack Guest

    Re: Returning a vector<int> from a dll


    A common way of handling this problem is to create two methods to your DLL.
    One to retrieve the vector<int> and one to return it for destruction.

    It's a little bit more troublesome on the client side forgetting to call
    the return data method is a prime source for memory links), so you may also
    want to create a simple wrapper class to handle the clean up.

    Using this method, however, you can avoid the memory problems without introducing
    a lot of memory copies.

    Wayne Mack
    PEC Solutions, Inc.

    "Sorin Gherman" <s_gherman@yahoo.com> wrote:
    >
    >I have a method exported from a VC++ dll that needs to create a vector<int>
    >and return it.
    >
    >Allocating it on the heap with new creates problem for the program using
    >the dll: deallocation may fail if the dll and the program are not compiled
    >with the same run-time library.
    >
    >So we decided to return it by value in order to avoid alocation/deallocation
    >problems.
    >
    >In dll I have:
    >
    >vector<int> createList()
    >{
    > vector<int> list;
    > ... //populate the list
    > return list;
    >}
    >
    >And in the program using the dll:
    >
    >...
    >{
    > vector<int> list = createList();
    > ...
    >} // --> when "list" exits out of scope here, an Access Violation occurs!
    >WHY??? Isn't the local object destroyed here? Why a memory conflict with
    >the dll??
    >
    >Thanks in advance,
    >Sorin Gherman



  5. #5
    Danny Kalev Guest

    Re: Returning a vector<int> from a dll



    Sorin Gherman wrote:
    > 1) Why are "list"'s element the ones allocated inside the dll? When vector<int>
    > 's copy-constructor is called, isn't the allocation for list being done in
    > the main program and just _copying_ the content of the one allocated inside
    > the dll?


    It's not that simple. In order to see why, let's review the semantic of
    returning objects by value in C++. To simplify the discussion, let's use
    the following contrived example:

    class A
    {
    public:
    A();
    A(const A&);
    ~A()
    };

    A func()
    {
    A a;
    return a;
    }

    int main()
    {
    A a2 = func();
    }

    When func() is called, it creates a local A object in its scope. Just
    before returning, it copy constructs that object into a temporary object
    of type A on the stack of the caller. Then, it destroys its local
    instance and exits.
    After the func() exits, the object a2 is copy constructed from temporary
    object that was left on the stack. Remember that this object was created
    in func(), probably using a different runtime library if func() is
    defined in a separate DLL. After the copy construction of a2 takes
    place, the temporary object is destroyed. At this point, the destruction
    uses a different runtime library (the application's runtime library).
    However, VC++ implements the return value optimization, whereby the
    recurrent copying and destruction of temporaries is eliminated. Instead,
    the compiler transform the code as follows: a reference to the target
    object a2 is passed to func(), which in turn constructs its object
    *directly* on the object passed. When func() returns, nothing happens
    because the a2 object is already constructed. Now, as you may have
    guessed, the object was constructed inside the dll, using library X, and
    is then destroyed outside the dll, using library Y. This is probably the
    cause of the crash.

    >
    > 2) Is it the particular way that VC 6.0 implemented vector that causes this
    > problem or is this according to STL's standard specs?


    DLL's are an MS specific feature so you won't find any referenced to
    their behavior in the standard.

    > Do you know if using
    > Borland C++ would cause the same problem?


    I haven't checked it but I suspect that the crash would simply appear
    elsewhere, because Borland doesn't implement the return value
    optimization.
    >
    > 3) How to solve the problem otherway than returning a pointer to a dynamically
    > allocated vector<int> and later delete it with another dll function, deleteVector(
    > vector<int> * ), since passing by value does not work ?


    You can define a smart pointer class that calls CreateList() in its ctor
    and calls another function in the DLL, say DestroyList() in its dtor
    that destroys the object from within the DLL. This is a bit kludgy but
    I've never been a great fonder of DLL's and MS-specific half-baked
    extensions to the language. The interaction is never smooth or bug free.

    Danny Kalev

    "The ANSI/ISO C++ Professional Programmer's Handbook"
    http://www1.fatbrain.com/asp/bookinf...sbn=0789720221

  6. #6
    Sorin Gherman Guest

    Re: Returning a vector<int> from a dll


    >class A
    >{
    >public:
    > A();
    > A(const A&);
    > ~A()
    >};
    >
    >A func()
    >{
    > A a;
    > return a;
    >}
    >
    >int main()
    >{
    > A a2 = func();
    >}
    >
    >When func() is called, it creates a local A object in its scope. ...

    Now, as you may have
    >guessed, the object was constructed inside the dll, using library X, and
    >is then destroyed outside the dll, using library Y. This is probably the
    >cause of the crash.


    Thank you very much for the answer, Danny! However, things are more complicated,
    I belive: for a simple object as A in your example, everything works out
    fine with the dll, I can return it by value without problems! Having vector<int>
    instead of A causes the crash.
    I tried to replicate the problem by building my own vector-like object,
    that is an object that has a method where memory is dynamically allocated
    for an internal member (as it happens with vector.push_back) and is freed
    on the destructor. I have overriden the copy-constructor and the operator=
    so that when a copy is created new memory is properly allocated. Even with
    such more complex object I could not replicate the pass-by-value crash!!
    So I suspect that the problems still lies within the heap-allocated memory
    in the dll (and not the stack one) but I just cannot figure out what exactly
    makes vector crash! Please let me know if you got any idea.

    >I've never been a great fonder of DLL's and MS-specific half-baked
    >extensions to the language. The interaction is never smooth or bug free.


    What do you use instead of dlls for Windows development?

    Thanks,
    Sorin Gherman


  7. #7
    Danny Kalev Guest

    Re: Returning a vector<int> from a dll



    Sorin Gherman wrote:
    >
    > >class A
    > >{
    > >public:
    > > A();
    > > A(const A&);
    > > ~A()
    > >};
    > >
    > >A func()
    > >{
    > > A a;
    > > return a;
    > >}
    > >
    > >int main()
    > >{
    > > A a2 = func();
    > >}
    > >
    > >When func() is called, it creates a local A object in its scope. ...

    > Now, as you may have
    > >guessed, the object was constructed inside the dll, using library X, and
    > >is then destroyed outside the dll, using library Y. This is probably the
    > >cause of the crash.

    >
    > Thank you very much for the answer, Danny! However, things are more complicated,
    > I belive: for a simple object as A in your example, everything works out
    > fine with the dll, I can return it by value without problems! Having vector<int>
    > instead of A causes the crash.
    > I tried to replicate the problem by building my own vector-like object,
    > that is an object that has a method where memory is dynamically allocated
    > for an internal member (as it happens with vector.push_back) and is freed
    > on the destructor. I have overriden the copy-constructor and the operator=
    > so that when a copy is created new memory is properly allocated. Even with
    > such more complex object I could not replicate the pass-by-value crash!!
    > So I suspect that the problems still lies within the heap-allocated memory
    > in the dll (and not the stack one) but I just cannot figure out what exactly
    > makes vector crash! Please let me know if you got any idea.


    The vector object has an internal object called allocator which does all
    the memory bookkeeping. The crash probably occurs when one of its
    methods is invoked. Your homemade vector class doesn't have an
    allocator, which is probably the cause of the crash.

    >
    > >I've never been a great fonder of DLL's and MS-specific half-baked
    > >extensions to the language. The interaction is never smooth or bug free.

    >
    > What do you use instead of dlls for Windows development?


    I don't:-) My apps don't have GUI. I write engines, device drivers,
    translators etc., and because I write for several platforms, I don't use
    non-portable features such as dll's. Lucky me:-)

    Danny

  8. #8
    John Reid Guest

    Re: Returning a vector<int> from a dll


    Danny Kalev <dannykk@inter.net.il> wrote:
    >
    >
    >Sorin Gherman wrote:
    >>
    >> >class A
    >> >{
    >> >public:
    >> > A();
    >> > A(const A&);
    >> > ~A()
    >> >};
    >> >
    >> >A func()
    >> >{
    >> > A a;
    >> > return a;
    >> >}
    >> >
    >> >int main()
    >> >{
    >> > A a2 = func();
    >> >}
    >> >
    >> >When func() is called, it creates a local A object in its scope. ...

    >> Now, as you may have
    >> >guessed, the object was constructed inside the dll, using library X,

    and
    >> >is then destroyed outside the dll, using library Y. This is probably

    the
    >> >cause of the crash.

    >>
    >> Thank you very much for the answer, Danny! However, things are more

    complicated,
    >> I belive: for a simple object as A in your example, everything works out
    >> fine with the dll, I can return it by value without problems! Having vector<int>
    >> instead of A causes the crash.
    >> I tried to replicate the problem by building my own vector-like object,
    >> that is an object that has a method where memory is dynamically allocated
    >> for an internal member (as it happens with vector.push_back) and is freed
    >> on the destructor. I have overriden the copy-constructor and the operator=
    >> so that when a copy is created new memory is properly allocated. Even

    with
    >> such more complex object I could not replicate the pass-by-value crash!!
    >> So I suspect that the problems still lies within the heap-allocated

    memory
    >> in the dll (and not the stack one) but I just cannot figure out what exactly
    >> makes vector crash! Please let me know if you got any idea.

    >
    >The vector object has an internal object called allocator which does all
    >the memory bookkeeping. The crash probably occurs when one of its
    >methods is invoked. Your homemade vector class doesn't have an
    >allocator, which is probably the cause of the crash.
    >
    >>
    >> >I've never been a great fonder of DLL's and MS-specific half-baked
    >> >extensions to the language. The interaction is never smooth or bug free.

    >>
    >> What do you use instead of dlls for Windows development?

    >
    >I don't:-) My apps don't have GUI. I write engines, device drivers,
    >translators etc., and because I write for several platforms, I don't use
    >non-portable features such as dll's. Lucky me:-)
    >
    >Danny


    The answer is probably simple.

    As the vector <int> is templated code, it is instantiated for a particular
    template class (in this case int) when the compiler sees it. In our case
    this is inside the DLL and in the DLL's client. Your class Sorin I am guessing
    isn't templated so all of the allocation/deallocation code is instantiated
    in the DLL (or in your DLL's client if you've chosen). If you give your vector<int>
    a specific allocator class that is not templated your problems should be
    resolved.

    I hope that's clear.

    John.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


Top DevX Stories

Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL


Sponsored Links