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

时间:2015-10-04 17:01:01

标签: c++ delete-operator

我正在学习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] = '\0';
            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");
}

2 个答案:

答案 0 :(得分:1)

您没有正确释放buffer。如果string中的所有字符都不等于delimiter此if语句中的代码:

if (string[k] == delimiter)

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

tokens[c] = nullptr;

会将tokens中存储的startBufferPointer的第一个元素设置为nullptr。在这种情况下,由于bufferbuffer的指针被“遗忘”,您正在泄漏main

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

答案 1 :(得分:0)

是的,没有内存泄漏,但为什么不使用能够保证内存的类型?

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] = '\0';
            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++;
    }
}

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