Returning STL containers by value corrupts heap...

S

Sachin Garg

Hi,

When trying to return objects of type

std::list<MyClass>

from my function, I get a corrupt heap.
(I checked using MSVC++ 7.0 runtime heap check facility)

Basically, I am creating a local object

std::list<MyClass> myObj;

After filling it up with data, at end I do a

return myObj;


And the process halts with a InvalidPointerInHeap runtime exception
(basically a corrupt heap).

I feel that the return statement must be calling the std::list copy
constructor, which must be performing a deep-copy of the container,
and then it must be deleting the local container.

Not to mention, myClass also has as a member, another stl list.

std::list<myOtherClass> myMemberList;

(I got the heap exception error message in the destructor of the inner
std:list)

Has anyone else faced similar issues with STL, or is this expected
behaviour, or is it that I am doing something wrong somewhere else?

Sachin Garg [India]
http://sachingarg.go.to
 
A

Andrew Koenig

When trying to return objects of type

std::list<MyClass>

from my function, I get a corrupt heap.

I would start by looking carefully at the MyClass copy constructor.
 
R

Rob Williscroft

Sachin Garg wrote in in comp.lang.c++:
Hi,

When trying to return objects of type

std::list<MyClass>

from my function, I get a corrupt heap.
(I checked using MSVC++ 7.0 runtime heap check facility)

You need to make a test programme that exhibits the problem,
then post it here:

There are several possibilities:

- Your "MyClass" object doesn't have the correct copy contructor
and assignment operator.
- You have corrupted the heap at some point prior to calling
your function.
- ...
- It is a compiler bug. (This is *very* rare, but it does happen).

A test case:

#include <iostream>
#include <list>
#include <cassert>

struct object
{
int i;
object( int ii ) : i ( ii ) {}
};

std::list< object > f()
{
std::list< object > r;
for ( int i = 0; i < 100; ++i )
{
r.push_back( i );
}
return r;
}

int main()
{
std::list< object > r = f();
std::list< object >::iterator
ptr = r.begin(),
lim = r.end()
;
for ( int i = 0; i < 100; ++i, ++ptr )
{
assert( ptr->i == i );
}
std::cout << "Ok\n";
}

Compiles and runs fine with VC++ 7.1.

Note that "object" doesn't have a User Defined copy ctor or assignment
operator, the compiler generated ones are fine in this case as object
doesn't hold any *resources* (new'd object's, files etc).

HTH.

Rob.
 
H

Howard Hinnant

Hi,

When trying to return objects of type

std::list<MyClass>

from my function, I get a corrupt heap.
(I checked using MSVC++ 7.0 runtime heap check facility)

Basically, I am creating a local object

std::list<MyClass> myObj;

After filling it up with data, at end I do a

return myObj;


And the process halts with a InvalidPointerInHeap runtime exception
(basically a corrupt heap).

I feel that the return statement must be calling the std::list copy
constructor, which must be performing a deep-copy of the container,
and then it must be deleting the local container.

Not to mention, myClass also has as a member, another stl list.

std::list<myOtherClass> myMemberList;

(I got the heap exception error message in the destructor of the inner
std:list)

Has anyone else faced similar issues with STL, or is this expected
behaviour, or is it that I am doing something wrong somewhere else?

Sachin Garg [India]
http://sachingarg.go.to

Most likely MyClass has an invalid copy constructor which is causing the
symptoms you're seeing.

-Howard
 
R

Richard Herring

Rob said:
Sachin Garg wrote in in comp.lang.c++:


You need to make a test programme that exhibits the problem,
then post it here:

There are several possibilities:

- Your "MyClass" object doesn't have the correct copy contructor
and assignment operator.
- You have corrupted the heap at some point prior to calling
your function.
- ...
- It is a compiler bug. (This is *very* rare, but it does happen).

- The function is returning a reference instead of a copy.

If the OP doesn't post actual code, how can we tell?
 
B

Buster

Sachin Garg wrote:

....
I feel that the return statement must be calling the std::list copy
constructor, which must be performing a deep-copy of the container,
and then it must be deleting the local container.
....

Has anyone else faced similar issues with STL, or is this expected
behaviour, or is it that I am doing something wrong somewhere else?

It is the required behaviour.

Regards,
Buster.
 
S

Sachin Garg

My code is exactly the same as the code posted above by Rob. Except
that my class has a few std::string elements (only). Its pretty
elementry code, so I was just making a wild check on if its a known
issue.

And, I have not defined my copy-constructor as I dont think its
needed.

I guess most probably it has something to do with the code executed
before this code or with the MSVC++ issues of using the correct /MT,
/ML, /MD etc... switch... (I had packeged this class in a DLL).
Anyway, I will check it out.

Thanks to all for offering help.
 
B

Buster

Sachin said:
Required behaviour? you sure? what do mean by required?

I'm pretty sure. Search the internet for "return value optimization",
"elimination of temporaries" and/or "elided copy constructor" and I'm
sure you'll come across some useful material that explains the exact
situation in detail. Be aware that the rules have recently been revised.
 
S

Sachin Garg

Buster said:
I'm pretty sure. Search the internet for "return value optimization",
"elimination of temporaries" and/or "elided copy constructor" and I'm
sure you'll come across some useful material that explains the exact
situation in detail. Be aware that the rules have recently been revised.

I did a quick search and read a bit on the topic, And understand the
inefficiencies. I better solution would probably be to, instead of
returning object, pass it by reference and then fill it up.

But I still dont understand why this can/should result in heap
corruption.

Sachin Garg [India]
http://sachingarg.go.to
 
B

Buster

Sachin said:
I did a quick search and read a bit on the topic, And understand the
inefficiencies. I better solution would probably be to, instead of
returning object, pass it by reference and then fill it up.

That's probably true if the list will be very large.
But I still dont understand why this can/should result in heap
corruption.

It shouldn't. Show us a complete program that exhibits the symptoms you
describe and we might be able to diagnose your problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top