using list

Discussion in 'C++' started by gigal, May 4, 2004.

  1. gigal

    gigal Guest

    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!
    gigal, May 4, 2004
    #1
    1. Advertising

  2. gigal wrote:
    > 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
    Stephen Waits, May 4, 2004
    #2
    1. Advertising

  3. "gigal" <> wrote in message
    news:hRGlc.16987$...
    > 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
    John Harrison, May 4, 2004
    #3
  4. Psuedo-dynamic allocation?

    "Stephen Waits" <> wrote a few days ago in a message
    about putting things in lists:

    > 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




    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Robbie Hatley, May 7, 2004
    #4
  5. Re: Psuedo-dynamic allocation?

    "Robbie Hatley"
    <-Xs-include-"[ciao]"-in-subject> wrote in
    message news:409b395d$1_1@127.0.0.1...
    > "Stephen Waits" <> wrote a few days ago in a message
    > about putting things in lists:
    >
    > > 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?


    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
    John Harrison, May 7, 2004
    #5
  6. Re: Psuedo-dynamic allocation?

    "John Harrison" <> wrote in message news:...

    > (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





    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Robbie Hatley, May 7, 2004
    #6
  7. Re: Psuedo-dynamic allocation?

    "Robbie Hatley"
    <-Xs-include-"[ciao]"-in-subject> wrote in
    message news:409b48f2_1@127.0.0.1...
    >
    > "John Harrison" <> wrote in message

    news:...
    >
    > > (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
    John Harrison, May 7, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. roopa
    Replies:
    6
    Views:
    715
    Jerry Coffin
    Aug 27, 2004
  2. dackz
    Replies:
    0
    Views:
    469
    dackz
    Feb 6, 2007
  3. Debajit Adhikary
    Replies:
    17
    Views:
    663
    Debajit Adhikary
    Oct 18, 2007
  4. OW Ghim Siong
    Replies:
    2
    Views:
    379
    Peter Otten
    Nov 30, 2010
  5. asil klin
    Replies:
    28
    Views:
    1,268
    Andreas Leitgeb
    Mar 5, 2011
Loading...

Share This Page