es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Fuga de memoria en C++ con puntero de clase

Estoy intentando escribir algunas clases, aprendiendo c++ y tengo el siguiente problema:

1. He creado una clase de la siguiente manera:

class my_string
{
private:
    char* buf = nullptr;
    unsigned int size = 0;

public:
    my_string() : buf(nullptr), size(0) // constructor por defecto
    {
    }

    my_string(const char* buffer) // constructor
    {
        size = strlen(buffer);
        buf = (char*)malloc(sizeof(char) * (size + 1)); // + 1 para mantener el carácter nulo
        memcpy(buf, buffer, size);
    }

    my_string(const my_string& obj) // constructor de copia
    {
        size = obj.size;
        buf = (char*)malloc(sizeof(char) * (size + 1)); // + 1 para mantener el carácter nulo
        memcpy(buf, obj.buf, size);
    }

    my_string& operator=(const my_string& obj) // asignación de copia
    {
        // limpiar cualquier dato existente

        // Copiar datos del nuevo objeto my_string asignado
        size = obj.size;
        buf = (char*)malloc(sizeof(char) * (size + 1)); // + 1 para mantener el carácter nulo
        memcpy(buf, obj.buf, size);
        return *this;
    }
};

2. Hago algo como esto:

while (true) {
    my_string* www4 = (my_string*)malloc(sizeof(my_string));
    www4[0] = "kek";
    free(&www4[0]);
    free(www4);
}

Y tengo una fuga de memoria: la memoria del proceso aumenta hasta 150 MB durante 1-2 segundos. ¿Qué está mal? ¿No libero todo?

Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema se encuentra en la línea www4[0] = "kek";. Aquí, estás asignando un literal de cadena a un objeto my_string, lo cual no es una operación válida. En el constructor de my_string, se asigna memoria utilizando malloc(), pero no se libera en ningún lugar. Por lo tanto, hay una fuga de memoria en el código. Para solucionarlo, puedes modificar el constructor de my_string y el operador de asignación por copia para utilizar free() y liberar la memoria asignada. Además, debes usar el operador new en lugar de malloc() para crear objetos de la clase my_string. Aquí tienes una implementación modificada de la clase my_string:

    class my_string
    {
    private:
        char* buf = nullptr;
        unsigned int size = 0;
    
    public:
        my_string() : buf(nullptr), size(0) // constructor por defecto
        {
        }
    
        my_string(const char* buffer) // constructor
        {
            size = strlen(buffer);
            buf = new char[size + 1]; // + 1 para mantener el carácter nulo
            memcpy(buf, buffer, size);
            buf[size] = '\0'; // añadir terminador nulo al final
        }
    
        my_string(const my_string& obj) // constructor de copia
        {
            size = obj.size;
            buf = new char[size + 1]; // + 1 para mantener el carácter nulo
            memcpy(buf, obj.buf, size);
            buf[size] = '\0'; // añadir terminador nulo al final
        }
    
        my_string& operator=(const my_string& obj) // asignación por copia
        {
            if (this != &obj) // comprobar si es una autoasignación
            {
                // liberar cualquier dato existente
                delete[] buf;
    
                // Copiar datos desde el nuevo objeto de my_string asignado
                size = obj.size;
                buf = new char[size + 1]; // + 1 para mantener el carácter nulo
                memcpy(buf, obj.buf, size);
                buf[size] = '\0'; // añadir terminador nulo al final
            }
            return *this;
        }
    
        ~my_string() // destructor
        {
            delete[] buf;
        }
    };
    

    Y aquí tienes el código modificado para crear y liberar objetos de my_string:

    while (true) {
        my_string* www4 = new my_string("kek");
        delete www4;
    }
    

    Usar new para crear objetos de my_string asegura que la memoria se asigna y se libera correctamente. El destructor de my_string se llama automáticamente cuando se utiliza el operador delete para liberar la memoria. Además, ten en cuenta que no es necesario llamar a free() en el objeto www4[0], ya que no se crea utilizando malloc().

Comments are closed.