mercredi 19 juillet 2017

How to prevent memory leak on allocation failure with consecutive uses of 'new'

I'm implementing a C-API with C++ and at the interface I have to convert C++ like data structures to existing data structures of the C-API.

I am responsible for the memory of the data structure, so I can use new and delete, but from my understanding the following C++11 code can have a memory leak (this is just a dumbed down example):

#include <string>
#include <new>

struct container {
    char *message;
};

/* converts an std::string to a C data structure */
container *create_container(const std::string& message) {
    container *c = nullptr;
    try {
        container *c = new container;
        c->message = new char[message.length() + 1];
        message.copy(c->message, message.length());
        c->message[message.length()] = '\0';
    } catch (std::bad_alloc exception) {
        return nullptr;
    }

    return c;
}

void destroy_container(container *c) {
    if (c != nullptr) {
        if (c->message != nullptr) {
            delete[] c->message;
        }
        delete c;
    }
}

int main(void) {
    container *c = create_container("message");
    destroy_container(c);

    return 0;
}

It would leak c if allocation of c->message fails.

So my question: How should I ideally deal with this situation?

What I came up with so far:

    /* ... */
    } catch (std::bad_alloc exception) {
        if (c != nullptr) {
            delete c;
        }
        return nullptr;
    }
    /* ... */

Is there a better way to do this in C++?

This problem can also happen in C++ only applications if memory is managed with new and delete and you happen to use new twice in the same try block that catches std::bad_alloc.

Could this maybe be solved using smart pointers or some other way?

Aucun commentaire:

Enregistrer un commentaire