我正在学习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");
}
答案 0 :(得分:1)
您没有正确释放buffer
。如果string
中的所有字符都不等于delimiter
此if语句中的代码:
if (string[k] == delimiter)
永远不会被执行,c
将保持0
。然后这一行:
tokens[c] = nullptr;
会将tokens
中存储的startBufferPointer
的第一个元素设置为nullptr
。在这种情况下,由于buffer
中buffer
的指针被“遗忘”,您正在泄漏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++;
}
}
现在所有内存都是自动管理的,而且几乎不可能泄漏。