简体   繁体   中英

How best can I fix my memory leak using smart pointers?

I stumbled upon this, which looks like a memory leak:

void method(const string param) {
    if (auto* object = createObject(param))
        use(object);
}

How best do I fix this memory leak?

Should I wrap the returned pointer in a unique pointer?

void method(const string param) {
    if (auto object = std::unique_ptr<Object>(createObject(param))
        use(object.get());
}

or:

void method(const string param) {
    if (std::unique_ptr<Object> object{createObject(param)})
        use(object.get());
}

It would be nice if C++ had type inference similar to Java's allowing something like:

 auto object = std::unique_ptr<>(createObject())

or

std::unique_ptr<> object{createObject()};

One worry I have about this is the unique_ptr constructor is being passed a raw pointer, so it wouldn't know how to destroy the referenced object. This is why I thought it might be better to instead return a unique pointer from createObject :

void method(const string param) {
    if (auto object = createObject(param))
        use(object.get());
}
std::unique_ptr<Object> createObject(){ return std::make_unique<Object>(...); }

From what I've read, this should now successfully deconstruct no matter what the Object is. Is it actually bad to return use a raw pointer to construct a unique pointer? It seems the reference is clearly no longer unique.

In both situations, use requires Object* so I have to use object.get() - I don't know if this is normal.

What's the general consensus on handling this situation?

You should avoid owning raw pointer, non-owning raw pointer are "fine" (caveat is that we don't know from pointer if it is owning or not).

Better would be to change

Object* createObject(const std::string& param) { return new Object(param); }

into

std::unique_ptr<Object> createObject(const std::string& param)
{
    return std::make_unique<Object>(param);
}

Then usage could indeed be similar to your proposal:

void use(Object*);
void method(const std::string& param)
{
    if (auto object = createObject(param))
        use(object.get());
}

As you check for nullptr for use , passing by reference might be more appropriate than by pointer:

void use(Object&);
void method(const std::string& param)
{
    if (auto object = createObject(param))
        use(*object);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM