How can I create a list entry without wasting memory?

Posted on 2000-03-24
Last Modified: 2010-04-02
//  This code produces two "Contigs" and I only want one.  
// This can be found at:
#include <list>

class Contig {
  char *id; // This is just for debug

  Contig( );
  Contig( char* name) ;
  ~Contig( );

Contig::Contig() {
  id = (char *) NULL ;

Contig::Contig( char* name) {
  id = name ;

Contig::~Contig() {
  if ( id ) cerr << " id = " << id << endl ;
  cerr << " Here we are in ~Contig" << endl ;

typedef  list<Contig>::iterator Contig_itr;


  list<Contig> AllContigs;

  AllContigs.push_front( Contig("what") ) ;  //  THE PROBLEM IS: This appears to create two "Contigs", not just one  
  Contig_itr a = (AllContigs.begin()) ;
  a->id = "A";

Question by:klopter
  • 4
  • 2
LVL 22

Accepted Solution

nietod earned 100 total points
ID: 2654873
>> AllContigs.push_front( Contig("what") ) ;  //  
>> THE PROBLEM IS: This appears to create
>> two "Contigs", not just one  
This is not a PROBLEM, but it might be a problem.  i.e the code works correctly, but might not be what you expected.  

It does create two Contigs.  One contig is the one you want, the one that gets stored in AllContigs.   The other contig is a "unnamed temporary".  This is an object created by the compiler and destroyed at the end of the statement.   These unamed temporaries can occur for a variety of reasons in a variety of circumstances, in this case you are forcing the compiler to create it by invoking a constructor, like in


this statement creates a contig object (but not a named varaible) and then destroys it.

So you see that two objects are getting created, but one is destroyed almost immediately.

LVL 22

Expert Comment

ID: 2654896
So the net result should be what you want.  i.e after the statement is executed there is only one object, the one in the list<>.  but the code is a little innefficient.  There are three operations that appear to not be needed, the creation of the temporary, the copying of the remporary to the list, and the destruction of the temporary.  This is one of the weaknesses of working with generic containers, especially the STL containers.  However if the class is relatively small and simple these three operations are probably pretty trivial and can be ignored.  If that is not the case, there sometimes are other things that can be done, like using reference counting to allow the object to be copied into the list without an actual copy being made.
LVL 22

Expert Comment

ID: 2654922
Another way around this is to have the container store pointers to dynamcially allocated object, then there is no need to copy items in to the container, but the problem with this is that it is easy to have memory leaks, and the main reason for using these containers is to avoid those memory leaks, so I don't really recommend it.

I guess I would first consider if this extra temproary is really all that costly.  If not, live with it, most poeple do.  If it is too costly, consider using reference counting to make the class more efficient.  That will probably have benefits in other cicumstances too.
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.


Author Comment

ID: 2654932
This is not likely to be a performance
critical section of code.  I was more
concerned about the apparent waste of
memory.  I won't pretend that I
like the creation, copy, delete aspect,
but it isn't a showstopper.  I know
that I can get rid of the cration and
deletion by going back to having a
temporary and it seems likely that
a good optimizing compiler could get
rid of all three.  (It can't in this
case because of my debug cout

Anyway, as long as you say that this
is the right semantics, I'll stick with
these for now.

Now, on the the erase problem.
More on that later.



Author Comment

ID: 2655076
I agree that the extra copies probably won't be a
significant perofrmance issue. I am not 100% positive
because basically this code is a graph manipulation
code, so I could imagine it is being an
issue.  But, though I don't immediately see
how to use reference counting to make this more
efficient, I take your word for it and will
cross that bridge if/when I come to it.

Thanks again,
LVL 22

Expert Comment

ID: 2655178
>> I know that I can get rid of the cration and
>> deletion by going back to having a
>> temporary
You can't get rid of it, but you can use 2 named temporary object to initialize many entries in the list, so yoiyu have only one extra construction and destruction, you still have lots of extra copies.

>>  and it seems likely that
>> a good optimizing compiler could get
>> rid of all three.  
Very unlikely.  It has to be able to determine that there will be no side effects from doing so and that is nearly impossible to do.  Any of these funtions could have nexpected side effects, like you might set the current screen color from them.  There are rules governing when the compiler can optimize away a temporaries and copy construction, but I can't remember them off-hand.  the rules are very restrictive.

>> But, though I don't immediately see
>> how to use reference counting to make this more
>> efficient,
whenever an object is slow to copy, reference counting can be used to make the copying nearly trivial.  If the objects will store lots of data, like large lists of other objects, they can be slow to copy.  If you reference count the class, you never need to copy it, you just copy a smart pointer class, which is fast to copy.

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question