calling placement new for elements of a deque

Discussion in 'C++' started by hbdevelop1, Feb 27, 2014.

  1. hbdevelop1

    hbdevelop1 Guest

    For optimisation reasons, I am re-using not used objects in my deque for new objects.
    I am doing that this way :
    void Score::Add(const char *str, Coordinates &sp)
    for(deque<Text>::iterator it=scores.begin();it!=scores.end(); ++it)


    I thought it would be more convenient to call the placement new on the notUsed object instead of Reset.
    How can I do this ?
    How can I get the address of the not used object so I can use it in the new placement operator?

    Thank you in advance
    hbdevelop1, Feb 27, 2014
    1. Advertisements

  2. You can get a reference to the object through operator* of the iterator.
    Then you can use the operator& to get the address of the object. Keep
    in mind, however, that generally the constructor calls need to match the
    destructor calls, so don't forget to destroy the object using a direct
    call to the destructor before constructing a new one there. Something like

    if (it->notUsed == 1)
    Text *pUnused = &(*it);
    pUnused->~Text(); // destroy
    new (pUnused) Text(str, sp);

    Remember to include <memory> for placement new operator.

    Not sure this is the best approach, though. Why do you think that using
    Reset is inconvenient?

    Victor Bazarov, Feb 27, 2014
    1. Advertisements

  3. hbdevelop1

    red floyd Guest

    The only reason I can see for using placement new instead of a reset is
    that some const members may need updating for the new data. Otherwise
    a reset should be fine.
    red floyd, Feb 27, 2014
  4. hbdevelop1

    hbdevelop1 Guest

    The reason why I don't want to use Reset is because it holds the same code as the constructor and is only used in this case.
    So I just wondered if I could get rid of Reset and use the constructor, for both, when pushing for the first time and when resetting.
    And now, red floyd has given another reason why I might want to use the placement new in future.

    Thank you very much Victor and red for your help and constructive feed back

    hbdevelop1, Feb 27, 2014
  5. hbdevelop1

    red floyd Guest

    1. Please don't top-post.

    2. I'd be VERRRRY careful about using placement new for that unless
    you ABSOLUTELY POSITIVELY need to do so. I would definitely prefer
    a Reset() function, or even an operator=(). Remember, readability
    and maintainability trump cleverness every single time.

    Also remember Hoare's law (also attributed to Knuth, or vice-versa):
    "Premature optimization is the root of all evil."

    Do you *really* need to do this "for efficency reasons"? Have you
    actually benchmarked to see if your insertion/deletion code is a
    bottleneck? Would an alternate data structure such as a std::list<>
    perhaps suit your purposes better?

    Think about that before embarking on this path.
    red floyd, Feb 27, 2014
  6. hbdevelop1

    hbdevelop1 Guest

    I used "optimization" for the wrong thing. In fact I wanted to mean writing less code, and not having two functions doing almost the same thing.

    I do agree with you on going about optimizing code using figures and through profiling.
    I liked your point on readability and maintainability and on thinking about other data structure.

    Thank you for your advice on being pragmatic in optimization
    hbdevelop1, Mar 3, 2014
  7. hbdevelop1

    Öö Tiib Guest

    Others have already answered about that placement new.

    Regardless if you use it or not I wanted to comment that typically such
    reuse is done with linked list of unused elements (not by for-cycling over
    whole container). It is because if the container is small and rarely added
    to / erased from then the whole reuse is likely not worth it ... but
    otherwise cycling in it is also wasteful. Something like that:

    void Score::Add( const char *str, Coordinates &sp )
    Text* toReplace = firstUnused;
    if ( toReplace == nullptr )
    scores.emplace_back( str, sp );
    firstUnused = ( toReplace->nextUnused == toReplace ) ? nullptr : toReplace->nextUnused;
    toReplace->swap( Text( str, sp ) );

    That involves that you build the linked list when elements become
    Öö Tiib, Mar 3, 2014
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.