Jump to content

  • Log In with Google      Sign In   
  • Create Account


C++ how to avoid calling destructor


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
32 replies to this topic

#21 Servant of the Lord   Crossbones+   -  Reputation: 16688

Like
1Likes
Like

Posted 29 January 2013 - 04:08 PM

Why don't you want the destructor called?

I quoted this post, to re-affirm that it is the "right" question.

 

If you are trying to save the copy, you can look into C++11's move semantics.

You could emplace_back(), if your compiler(s) support it (C++11 once again).

 

I quoted the above two posts to re-affirm that they are the "right" answer. Both require C++11.

If you aren't C++11, you could do something like this instead:

std::vector<some_class> array;

void pushback_function()
{
    array.push_back(some_class());
    array.back().heavyInitializationStuff();
}

But that violates RAII, as so should be a questionable move to make. If you don't have C++11, your heavy class could implement some kind of "swap" function just for itself, to transfer ownership of data pointers or something.

Instead, I'll ask my own "right" question: Is this an actual need for being optimized after measuring your existing application's performance using profiling to find the bottlenecks, or is this pre-optimization? I wouldn't be surprised if your compiler optimized your existing code as it is.

Why is the copy such a huge deal?

Well, your actual question was, how do you avoid the destructor. So I guess my question should be, why is the destructor such a big deal? What are you doing in it?


It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.

[Fly with me on Twitter] [Google+] [My broken website]

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.                                                                                                                                                       [Need free cloud storage? I personally like DropBox]

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


Sponsor:

#22 ChrisBarnhouse   Members   -  Reputation: 194

Like
0Likes
Like

Posted 29 January 2013 - 04:19 PM

Personally, I always use pointers in container templates. This avoid unnecessary memory copies and constructor/destructor calls.

I'm a bit of a memory nazi though, so I prefer doing the new and delete myself.



#23 jwezorek   Crossbones+   -  Reputation: 1606

Like
5Likes
Like

Posted 29 January 2013 - 04:22 PM

This thread is spiraling all over the place because I think people are making all kinds of assumptions about why the OP is asking this question. The OP needs to be clearer about what he is trying to do. The most likely things are

(1) The destructor is doing something it shouldn't be doing -- executing some logic that should be elsewhere.
(2) Local function scope is not the right scope for whatever is going on.

but without more information, who knows?

Edited by jwezorek, 29 January 2013 - 04:23 PM.


#24 Servant of the Lord   Crossbones+   -  Reputation: 16688

Like
6Likes
Like

Posted 29 January 2013 - 04:28 PM

As for the OP, he is the one that didn't want to call the constructor. I didn't question it lol (ironically in fear of losing rep haha).

 

If someone is holding a gun with the safety on and are pointing it at their feet pulling the trigger repeatedly, and are asking, "How do I take off the safety?", please don't tell them the answer without first asking them why, and informing them of the danger that the bullets pose to their feet. And certainly don't hand them a shotgun saying, "Here, this works better" without explaining that the shotgun will blow off their entire leg rather than just their foot. mellow.png

 

Not calling a destructor is bad enough, not even freeing the memory is worse. But giving them a solution that takes something that is very well known (std::shared_ptr), and takes it's very well known benefit and guarantee (that it frees your memory for you), and blocking that one guarantee from actually working? That's just pure evillaugh.png

 

Asking someone why they want to do something that can seriously hurt them, and informing them of the danger, is one of the kindest things you can do.

 

I wasn't one of the people who rated you down, but remember that people are downrating your post, not downrating you as an individual. The friendliest people in the world can give bad advice, and it's important to highlight the bad advice as bad, so others are aware of it, even when you like the person giving the advice. smile.png


It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.

[Fly with me on Twitter] [Google+] [My broken website]

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.                                                                                                                                                       [Need free cloud storage? I personally like DropBox]

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


#25 SiCrane   Moderators   -  Reputation: 9337

Like
7Likes
Like

Posted 29 January 2013 - 04:42 PM

Personally, I always use pointers in container templates. This avoid unnecessary memory copies and constructor/destructor calls.
I'm a bit of a memory nazi though, so I prefer doing the new and delete myself.

Note that you may be incurring performance penalties in the form of extra cache misses from loss of data locality if you take that route.

#26 Eric Lengyel   Crossbones+   -  Reputation: 2156

Like
0Likes
Like

Posted 29 January 2013 - 05:58 PM

That won't suppress the some_class destructor being called when array is deallocated or otherwise shuffles elements.

I'm not sure that's an issue in this case, as the OP only specified suppressing the destructor of the temp object. One problem with the locally allocated char array is that it may not have the correct alignment for some_class. A similar example from the C++98 standard had to be changed in the C++03 standard to use dynamic allocation of the char array so that alignment requirements were met.

 

Then you can declare the char storage with alignas(some_class) in C++11, or __declspec(align(__alignof(some_class))) in Visual C++.



#27 phantom   Moderators   -  Reputation: 6663

Like
4Likes
Like

Posted 29 January 2013 - 06:05 PM

Personally, I always use pointers in container templates. This avoid unnecessary memory copies and constructor/destructor calls.
I'm a bit of a memory nazi though, so I prefer doing the new and delete myself.


Unfortunately your paranoia over copying means that you are pretty much dropping performance all over the place as between the de-referencing and the data misses you are giving the CPU a hard time.

Memory is SLOW, if you can you ALWAYS want to keep things as close together as you can when processing to take advantage of pre-fetching and caching of data. Stalling out the CPU for many cycles while it wanders off to find the data you've just asked for is not a productive use of anyone's time.

Edit: Part of me thinks that everyone should be made to program on a system with limited cache and an in-order arch. just so they can appreciate how many sins an OoO processor covers up...

Edited by phantom, 29 January 2013 - 06:06 PM.


#28 Cornstalks   Crossbones+   -  Reputation: 6966

Like
2Likes
Like

Posted 29 January 2013 - 06:17 PM

It should compile, I would be interested in knowing why it doesnt for you.

Well, the obvious one is that new temp() should be new some_class(). It's also missing a right parenthesis. I can't comment on the bind business, I just checked it with a C++11 compiler and simply passed nullFunc instead of binding anything.

 

As for (properly) using smart pointers, once you get this to compile, it works really nicely for C libraries (with the appropriate deleter func added) without needing to wrap loads of stuff in C++ classes. Though the problem in this thread isnt perhaps the best use-case for it.

That might be a neat trick for cleaning up pointers from C APIs, but I hope you're very clear with documentation if you do that because it's not what people really expect with a shared_ptr. Additionally, you could just wrap the thing up in a proper class or struct and do the freeing in the destructor (which is probably more idiomatic). Anyway, the real problem I have with that snippet is that it's encouraging him to leak memory and completely negating the benefits of shared_ptr. I think that might be a useful trick (and thanks for this explanatory paragraph), but you're last sentence is the key. The "job" discussed in this thread requires a hammer, not a screw driver smile.png Telling someone to use a screw driver to nail something in (even if you have good intentions) is just... yeah...


Edited by Cornstalks, 29 January 2013 - 06:18 PM.

[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#29 dark-fire   Members   -  Reputation: 125

Like
-2Likes
Like

Posted 30 January 2013 - 05:53 AM

I think eighter creating a pointer or a static member would solve your issue



#30 SiCrane   Moderators   -  Reputation: 9337

Like
2Likes
Like

Posted 30 January 2013 - 09:02 AM

Making an object static doesn't eliminate the destructor call, it just makes the destructor call happen at some later, indeterminate time.

#31 wintertime   Members   -  Reputation: 1575

Like
0Likes
Like

Posted 31 January 2013 - 12:49 PM

Huge discussion for when he probably just wants something like this:

std::vector<some_class> array;

void pushback_function()
{
    some_class temp;
    array.push_back(std::move(temp));
}

... to avoid an extraneous copy constructor and destructor call, but not eliminate destructors everywhere.



#32 SiCrane   Moderators   -  Reputation: 9337

Like
1Likes
Like

Posted 31 January 2013 - 01:25 PM

That still has an extraneous construction and destruction, nor does it necessarily avoid an expensive copy operation. std::move() isn't magic. It can only move objects that have a properly defined move constructor. If you have std::move() available then you should also have emplace_back() which will avoid the entire temporary object in the first place.

#33 iMalc   Crossbones+   -  Reputation: 2250

Like
1Likes
Like

Posted 01 February 2013 - 05:58 PM

Any chance that we can see the real code yet?

I think there's a high probability that the entire problem here is a lack of following the Rule of three.

Edited by iMalc, 01 February 2013 - 06:00 PM.

"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS