Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Idiomatic C++ does not rely on manual memory management—it relies on deterministic memory management. Use unique_ptr, or shared_ptr when it makes sense (hint: it rarely does).


In theory you have every single leakable resource wrapped up in a RAII container or a smart pointer. In reality you're almost always dealing with raw pointers coming from a lower level C API or old C++ code or some kind of object handle you haven't wrapped yet.

Of course the recommendation from Stroustrup & Sutter is to use the new smart pointers for everything but I think it will be a few years at least before most people can follow that advice.


Typically what I do in that situation is lightly wrap the API. For instance:

    Image* image = allocate_image(…);
    …
    deallocate_image(image);

    ↓

    struct ImageDeleter {
        void operator()(void* image) const {
            deallocate_image(image);
        }
    };

    unique_ptr<Image, ImageDeleter> image(allocate_image(…));
That certainly can’t work everywhere, but I have yet to be failed by it.


You can reduce verbosity of the code by passing destructor function directly to unique_ptr constructor:

    std::unique_ptr<Image, void (*)(Image *)>(image, deallocate_image);


Cool, thanks for the tip. I meant to offer an example for the general case.


People who don't do this are just asking for it.


That's a lot of boilerplate code. Okay there are macros to wrap such things, but I guess it's things like this that would make the future reader of the code puzzled.


jmq & basman provide examples of how to do it succinctly.


Or, perhaps easier:

scoped_ptr<Image> image(allocate_image(...));


Sure. And using deep-thrown (i.e. thrown across module/library boundaries -- often exceptions are local tricks used within tightly coupled code) exceptions in an application where you're dealing with such pointers would be bad design.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: