-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
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
|
Bookmarks