使用指定内存构造对象并使用free(mem)释放,导致内存泄漏

问题描述 投票:0回答:1

有一段代码片段使用指定的内存构造一个对象,如图所示。当我使用 free(mem) 释放指定的内存时,我注意到 Node 类的析构函数没有被调用。这是不是意味着Node中字符串类型key的内存空间没有被释放呢?我怀疑可能存在内存泄漏,但是当我运行测试循环时,我没有看到内存不断增加。相反,当我编写自己的 MyString 类(其中包含 char* 数据和 int length)并用它替换 std::string 时,我发现在测试循环期间内存不断增加,似乎在泄漏。这是为什么? std::string 有什么独特的特征吗?

// using K = std::string;

struct Node {
    K key;
    Node(){}
    Node(const K& k): key(k) {}

    ~Node() {
      printf(" ~node\n");
    }

    void cleal_Key() {
        // key.~K();
        // printf("  clear node\n");
    }
};

void test() {
    for (int i = 0; i< 100000; i++) {
        char* mem = (char*)malloc(sizeof(Node));
        Node* node = new (mem) Node();
        node->key = "abcdfefdf" + std::to_string(i);
        free(mem); 
    }
}

我测试了 std::string 和 MyString,我发现非常令人惊讶的是 std::string 没有内存泄漏。

c++ memory memory-leaks
1个回答
0
投票

您观察到的行为与

std::string
管理内存的方式有关。在您的
Node
类中,当您使用
std::string
作为成员 (
K key
) 时,
std::string
类会在内部管理其内存分配和释放。

在您的

test
函数中,当您使用
Node
malloc
分配内存,然后使用放置
Node
构造
new
对象时,您并没有显式调用析构函数。然而,
std::string
类负责其内存管理。当您调用
free(mem)
时,它只会释放为
Node
对象分配的内存,而不是其中的
std::string
对象。

此行为特定于

std::string
的工作方式。它在内部使用动态内存分配并在其析构函数中处理内存释放。
std::string
内容的内存与
std::string
对象本身的内存分开管理。

现在,如果您将

std::string
替换为您自己的
MyString
类,并且您的
MyString
类未在其析构函数中正确管理内存,您可能会观察到内存泄漏。

以下是内存泄漏

MyString
类的示例:

struct MyString 
{
    char* data;
    int length;

    MyString() : data(nullptr), length(0) {}

    MyString(const char* str)
    {
        length = strlen(str);
        data = new char[length + 1];
        strcpy(data, str);
    }

    ~MyString()
    {
        // This destructor is missing the necessary memory deallocation
        // delete[] data; // Uncomment this line to fix the memory leak
    }
};

如果您的

MyString
类具有可以正确释放内存的析构函数,则您不应观察到任何内存泄漏。

总之,您在

std::string
中看到的行为是因为
std::string
管理其内存,并且其析构函数负责释放分配的内存。如果将其替换为您的类 (
MyString
),请确保您的类在其析构函数中正确处理内存以避免内存泄漏。

© www.soinside.com 2019 - 2024. All rights reserved.