提问者:小点点

使用模板类的自定义列表类型中的内存泄漏


我试图使用C++template特性在C++中创建一个自定义列表类型,并且我已经使它能够正确地编译和运行不同类型的值列表,甚至是值列表,但是当我用Valgrind运行该程序时,我遇到了内存泄漏。

我已经盯着这个问题看了很久了,但还没有得到任何进一步的修复,尽管我确信有一些非常明显的东西是我遗漏的,一些经验丰富的人可以指出来。

下面是我的列表类型:

template<typename listType>
class List {
public:
    listType *data;
    unsigned int listLength;

    List() {
        listLength = 0;
        data = (listType *) malloc(sizeof(listType));
    }

    explicit List(unsigned int len) {
        listLength = len;
        // I have tried freeing "data" here but that leads to more errors
        //  ---------------------- Valgrind says the leak is here ----------------------
        data = (listType *) malloc(sizeof(listType) * len);
        for (unsigned int i = 0; i < len; i++) {
            data[i] = listType();
        }
    }

    List<listType> &operator=(const List<listType> &other) {
        if (this != &other) {
            listLength = other.listLength;
            data = (listType *) malloc(sizeof(listType) * other.listLength);
            memcpy(data, other.data, sizeof(listType) * other.listLength);
        }

        return *this;
    }

    ~List() {
        if (std::is_fundamental<listType>::value) {
            free(data);
        } else {
            for (unsigned int i = 0; i < listLength; i++) {
                data[i].~listType();
            }
            free(data);
        }
    }

    listType &operator[](unsigned int index) const {
        return data[index];
    }
};

如果有人能解释我如何解决这个问题,以及为什么会发生这种情况,那将是非常有帮助的,因为我已经在这个问题上困了好几个小时了。


共1个答案

匿名用户

正如WhozCraig和Yksisarvinen在评论中指出的,使用new[]delete[](而不是使用malloc()函数)可以正确分配和释放内存,生成的代码如下所示,以备不时之需:

template<typename listType>
class List {
public:
    listType *data;
    unsigned int listLength;

    List() {
        listLength = 0;
        data = (listType *) malloc(sizeof(listType));
    }

    explicit List(unsigned int len) {
        listLength = len;
        data = new listType[len];
    }

    List<listType> &operator=(const List<listType> &other) {
        if (this != &other) {
            listLength = other.listLength;
            delete[] data;
            data = new listType[other.listLength];
            memcpy(data, other.data, sizeof(listType) * other.listLength);
        }

        return *this;
    }

    ~List() {
        delete[] data;
    }

    listType &operator[](unsigned int index) const {
        return data[index];
    }
};