Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

calling placement new for elements of a deque

84 views
Skip to first unread message

hbdev...@gmail.com

unread,
Feb 27, 2014, 12:50:29 AM2/27/14
to
Hello
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)
{
if(it->notUsed==1)
{
it->Reset(str,sp);
return;
}
}

scores.push_back(Text(str,sp));
}

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

Victor Bazarov

unread,
Feb 27, 2014, 8:43:12 AM2/27/14
to
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);
return;
}

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?

V
--
I do not respond to top-posted replies, please don't ask

red floyd

unread,
Feb 27, 2014, 12:53:31 PM2/27/14
to
On 2/27/2014 5:43 AM, Victor Bazarov wrote:

>
> if (it->notUsed == 1)
> {
> Text *pUnused = &(*it);
> pUnused->~Text(); // destroy
> new (pUnused) Text(str, sp);
> return;
> }
>
> 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?

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.

hbdev...@gmail.com

unread,
Feb 27, 2014, 5:39:23 PM2/27/14
to

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

red floyd

unread,
Feb 27, 2014, 6:28:21 PM2/27/14
to
On 2/27/2014 2:39 PM, hbdev...@gmail.com wrote:
>
> 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
>

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.





hbdev...@gmail.com

unread,
Mar 2, 2014, 7:38:44 PM3/2/14
to
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

Öö Tiib

unread,
Mar 3, 2014, 12:00:41 AM3/3/14
to
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 );
}
else
{
firstUnused = ( toReplace->nextUnused == toReplace ) ? nullptr : toReplace->nextUnused;
toReplace->swap( Text( str, sp ) );
}
}

That involves that you build the linked list when elements become
unused.
0 new messages