我是否正确释放了堆中的内存

Am I releasing the memory in the heap correctly?

本文关键字:内存 放了 释放 是否      更新时间:2023-10-16

我正在学习C/c++,我正在做的练习是创建一个计算算术表达式的程序。

为了完成这个练习,我需要一个通用的函数,它能够对字符串进行标记。由于要解析的字符串的大小在编译时未知,因此我必须在堆中动态分配一些数据。

工作完成后,堆中的内存可以被释放。

我的问题很简单:我释放内存正确吗?请在评论中提问。

标记功能
char** Tokenize(const char delimiter, const char* string)
{
    const char* pString = string;
    char** tokens = new char*[strlen(string)];
    char* buffer = new char[strlen(string)];
    char* pointer = buffer;
    int c = 0;
    for (int k = 0; k < strlen(string); k++)
    {
        if (string[k] == delimiter)
        {
            buffer[k] = '';
            tokens[c] = pointer;
            pointer = buffer + k + 1;
            c++;
            continue;
        }
        buffer[k] = string[k];
    }
    tokens[c] = nullptr;
    return tokens;
}

测试Tokenize函数并释放堆的主函数。

int main()
{
    char** tokens = Tokenize('.', "192.168.1.1");
    char** startTokensPointer = tokens;
    char* startBufferPointer = *tokens;
    while (*tokens != nullptr)
    {
        cout << *tokens << endl;
        tokens++;
    }
    delete[] startTokensPointer; //Releases tokens??
    delete[] startBufferPointer; //Releases buffer??
    system("PAUSE");
}

您没有正确地释放buffer。如果string中没有一个字符等于delimiter,则If语句中的代码:

if (string[k] == delimiter)

将永远不会执行,c将保持0。然后这一行:

tokens[c] = nullptr;

tokens中存储在startBufferPointer中的第一个元素设置为nullptr。在这种情况下,您正在泄漏buffer,因为指向buffer的指针在main中被"遗忘"。

tokens在所有情况下都正确释放

是的,没有内存泄漏,但是为什么不使用一个可以保证内存泄漏的类型呢?

struct Tokens
{
  explicit Tokens(size_t len) : tokens(new char*[len]), buffer(new char[len])
  { }
  std::unique_ptr<char*[]> tokens;
  std::unique_ptr<char[]> buffer;
};
Tokens Tokenize(const char delimiter, const char* string)
{
    auto len = strlen(string);
    Tokens result(len);
    char* pointer = result.buffer.get();
    int c = 0;
    for (size_t k = 0; k < len; k++)
    {
        if (string[k] == delimiter)
        {
            result.buffer[k] = '';
            result.tokens[c] = pointer;
            pointer = result.buffer.get() + k + 1;
            c++;
            continue;
        }
        result.buffer[k] = string[k];
    }
    result.tokens[c] = nullptr;
    return result;
}
int main()
{
    auto tok = Tokenize('.', "192.168.1.1");
    char** tokens = tok.tokens.get();
    while (*tokens != nullptr)
    {
        cout << *tokens << endl;
        tokens++;
    }
}

现在所有的内存都是自动管理的,几乎不可能泄漏。