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
Comment Utility
>> 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

Comment Utility
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

Comment Utility
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.
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.


Author Comment

Comment Utility
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

Comment Utility
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

Comment Utility
>> 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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

763 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now