using list

G

gigal

For some "new" created objects of class A with pointers, how to put them
into a list, list<class A> l?

p1 = new A();
p2 = new A();
P3 = new A();
....

Thank you very much!
 
S

Stephen Waits

gigal said:
For some "new" created objects of class A with pointers, how to put them
into a list, list<class A> l?

Using your example:

std::list<A> listA;
A* p1 = new A();
A* p2 = new A();
A* p3 = new A();
// note dereferences below
listA.push_back(*p1); // add to end of list
listA.push_front(*p2); // add to front of list
listA.insert(listA.begin(),*p3); // insert before iterator

That said, this probably isn't what you really want. You see, each
element you put on the list is a copy, so it's independently allocated
and copy constructed.

Instead, you may want a list of pointers to A:

std::list<A*> listPA;
A* p1 = new A();
listPA.push_back(p1);

But then you'll need to deal with heap management on your own, and deal
with pointer reference counting, etc. (use smart pointer here?). It's
generally pretty ugly, but, if copy construction is REALLY expensive,
and you need the performance, this may be the best way to go. Avoid if
possible.

That said, perhaps you should really be doing something like this instead:

std::list<A> listA;
listA.push_back( A() );

Here we're pushing back a temporary element that we're constructing on
the stack. A copy is made and inserted into the list. Now the list
deals with the heap for you.

HTH...

--Steve
 
J

John Harrison

gigal said:
For some "new" created objects of class A with pointers, how to put them
into a list, list<class A> l?

p1 = new A();
p2 = new A();
P3 = new A();
...

You have a list of values, but you are using pointers. One of these two is
wrong.

Either do this

list<A> l;
l.push_back(A());

l.push_back(A());

l.push_back(A());

or this

list<A*> l;
l.push_back(new A());

l.push_back(new A());

l.push_back(new A());

Usually the first is recommended because its much easier to avoid pointers,
but it all depends on exactly what you are trying to do.

john
 
R

Robbie Hatley

That said, perhaps you should really be doing something like this instead:

std::list<A> listA;
listA.push_back( A() );

Here we're pushing back a temporary element that we're constructing on
the stack. A copy is made and inserted into the list. Now the list
deals with the heap for you.

I've been wondering about that. I've got an application at work for a
map of structs which contain deques. A bit cumbersome of a construct,
and yet very useful:

struct TempHumData
{
time_t TimeStamp;
double Temp;
double Hum;
}

struct ZoneRTData
{
deque<TempHumData> TempHumDeque;
bool Disable;
}

map<unsigned long int, ZoneRTData> ZoneMap;

unsigned long int ZID = 3702; // separate id # for each zone; can be dozens

ZoneMap.insert(make_pair(ZID, ZoneRTData()));

So you're saying that even when I let the ZoneRTData implicit default
constructor create a new, unnamed object (which would chain to the
implicit default constructor for deque<TempHumData>), and when I let
make_pair() dynamically create a new, unnamed pair, and then store the
pair in a map, the memory will all be handled automatically? And deallocated
at the appropriate time? I've been worrying about that, because this construct
may hold a lot of data (megabytes), and memory leaks would be disastrous.
(It's a program that may run for months without being shut down, so leaks
would accumulate rapidly.)

I realize some aspects will have to be handled manually (eg, purge old data
from deques to keep size down); but as long as the memory is actually
free'd when items are pop'ed from deques or zones are erase'd from the map,
all should be well.

(I've co-workers who'd rather write it all in C and handle the memory
manually with malloc and free. I'm trying to convince them my way
is better.)

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
J

John Harrison

"Robbie Hatley"
I've been wondering about that. I've got an application at work for a
map of structs which contain deques. A bit cumbersome of a construct,
and yet very useful:

struct TempHumData
{
time_t TimeStamp;
double Temp;
double Hum;
}

struct ZoneRTData
{
deque<TempHumData> TempHumDeque;
bool Disable;
}

map<unsigned long int, ZoneRTData> ZoneMap;

unsigned long int ZID = 3702; // separate id # for each zone; can be dozens

ZoneMap.insert(make_pair(ZID, ZoneRTData()));

So you're saying that even when I let the ZoneRTData implicit default
constructor create a new, unnamed object (which would chain to the
implicit default constructor for deque<TempHumData>), and when I let
make_pair() dynamically create a new, unnamed pair, and then store the
pair in a map, the memory will all be handled automatically?

Yes. But I'd quibble about your terminology. make_pair does not create
anything dynamically, that would imply use of new, which make_pair does not
use.
And deallocated
at the appropriate time?

Yes that too.

I've been worrying about that, because this construct
may hold a lot of data (megabytes), and memory leaks would be disastrous.
(It's a program that may run for months without being shut down, so leaks
would accumulate rapidly.)

I realize some aspects will have to be handled manually (eg, purge old data
from deques to keep size down); but as long as the memory is actually
free'd when items are pop'ed from deques or zones are erase'd from the map,
all should be well.

All will be well!
(I've co-workers who'd rather write it all in C and handle the memory
manually with malloc and free. I'm trying to convince them my way
is better.)

Old timers.

john
 
R

Robbie Hatley

John Harrison said:
(answers to my fears re. memory leaks)

Thanks for the clarification.
... Yes. But I'd quibble about your terminology. make_pair does not create
anything dynamically, that would imply use of new, which make_pair does not
use....

Ah, you mean "dynamically" in the sense of creating objects which still
exist after the code that created them goes out of scope:

void Dweevil (unsigned check)
{
double * Qbert = new unsigned double;
... (hundreds of lines of code) ...
return;
} // leave scope
// Oops! Forgot to delete Qbert ! Memory leak!

I meant "dynamic", however, in the sense of not specifying in advance
how many objects will be created or what their names will be.

This is the kind of thing I'd call "pseudo-dynamic":

struct Glurk
{
char broil;
long shot;
}
void Bard (double bubble)
{
list<Glurk> Grendel;
if (bubble > 19.7)
{
Grendel.push_back(Glurk()); // pseudo-dynamically create new Glurk
}
... (hundreds of lines of code) ...
return;
} // leave scope, free memory.

This can be a very useful concept, I'm beginning to see.

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
J

John Harrison

"Robbie Hatley"
(answers to my fears re. memory leaks)

Thanks for the clarification.
... Yes. But I'd quibble about your terminology. make_pair does not create
anything dynamically, that would imply use of new, which make_pair does not
use....

Ah, you mean "dynamically" in the sense of creating objects which still
exist after the code that created them goes out of scope:

Right.

[snip]


This is the kind of thing I'd call "pseudo-dynamic":

struct Glurk
{
char broil;
long shot;
}
void Bard (double bubble)
{
list<Glurk> Grendel;
if (bubble > 19.7)
{
Grendel.push_back(Glurk()); // pseudo-dynamically create new Glurk
}
... (hundreds of lines of code) ...
return;
} // leave scope, free memory.

This can be a very useful concept, I'm beginning to see.

What you are calling pseudo-dynamic objects are one example of what the C++
standard calls temporaries.

Note that in your code the temporary Glurk() it not destroyed when you exit
Bard, its destroyed at the end of the statement on which it is created. What
goes into Grendel is a copy of that temporary, and it lives until it is
removed from the list or the list is destroyed.

john
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top