gpt4 book ai didi

c++ - 内存没有被释放,导致巨大的内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:05:22 24 4
gpt4 key购买 nike

不幸的是,这些解决方案尚未奏效;将 result.values 指针设置为 0 实际上并不能减轻内存使用量。我也试过用 free(result.values) 代替它,但这是不希望的,因为它会删除我的字符串。

编辑 2:我将尝试编写堆栈析构函数。

编辑 3:明白了。感谢 DeadMG,编写了一个 free(values) 的析构函数,完美地完成了这个技巧!哇...这么简单。

在我的 C++ Unicode 库中,ustring 类为 char* 值和其他 ustring 值设置了 operator= 函数。在进行简单的内存泄漏测试时:

#include <cstdio>
#include "ucpp"
main() {
ustring a;
for(;;)a="MEMORY";
}

程序使用的内存不受控制地增长(具有大量内存泄漏的程序的特征),即使我已经向这两个函数添加了 free() 调用。我不确定为什么这是无效的(我是否在其他地方错过了 free() 调用?)

这是当前的库代码:

#include <cstdlib>
#include <cstring>
class ustring {
int * values;
long len;
public:
long length() {
return len;
}
ustring() {
len = 0;
values = (int *) malloc(0);
}
ustring(const ustring &input) {
len = input.len;
values = (int *) malloc(sizeof(int) * len);
for (long i = 0; i < len; i++)
values[i] = input.values[i];
}
ustring operator=(ustring input) {
ustring result(input);
free(values);
len = input.len;
values = input.values;
return * this;
}
ustring(const char * input) {
values = (int *) malloc(0);
long s = 0; // s = number of parsed chars
int a, b, c, d, contNeed = 0, cont = 0;
for (long i = 0; input[i]; i++)
if (input[i] < 0x80) { // ASCII, direct copy (00-7f)
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = input[i];
} else if (input[i] < 0xc0) { // this is a continuation (80-bf)
if (cont == contNeed) { // no need for continuation, use U+fffd
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = 0xfffd;
}
cont = cont + 1;
values[s - 1] = values[s - 1] | ((input[i] & 0x3f) << ((contNeed - cont) * 6));
if (cont == contNeed) cont = contNeed = 0;
} else if (input[i] < 0xc2) { // invalid byte, use U+fffd (c0-c1)
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = 0xfffd;
} else if (input[i] < 0xe0) { // start of 2-byte sequence (c2-df)
contNeed = 1;
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = (input[i] & 0x1f) << 6;
} else if (input[i] < 0xf0) { // start of 3-byte sequence (e0-ef)
contNeed = 2;
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = (input[i] & 0x0f) << 12;
} else if (input[i] < 0xf5) { // start of 4-byte sequence (f0-f4)
contNeed = 3;
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = (input[i] & 0x07) << 18;
} else { // restricted or invalid (f5-ff)
values = (int *) realloc(values, sizeof(int) * ++s);
values[s - 1] = 0xfffd;
}
len = s;
}
ustring operator=(const char * input) {
ustring result(input);
free(values);
len = result.len;
values = result.values;
return * this;
}
ustring operator+(ustring input) {
ustring result;
result.len = len + input.len;
result.values = (int *) malloc(sizeof(int) * result.len);
for (long i = 0; i < len; i++)
result.values[i] = values[i];
for (long i = 0; i < input.len; i++)
result.values[i + len] = input.values[i];
return result;
}
ustring operator[](long index) {
ustring result;
result.len = 1;
result.values = (int *) malloc(sizeof(int));
result.values[0] = values[index];
return result;
}
operator char * () {
return this -> encode();
}
char * encode() {
char * r = (char *) malloc(0);
long s = 0;
for (long i = 0; i < len; i++) {
if (values[i] < 0x80)
r = (char *) realloc(r, s + 1),
r[s + 0] = char(values[i]),
s += 1;
else if (values[i] < 0x800)
r = (char *) realloc(r, s + 2),
r[s + 0] = char(values[i] >> 6 | 0x60),
r[s + 1] = char(values[i] & 0x3f | 0x80),
s += 2;
else if (values[i] < 0x10000)
r = (char *) realloc(r, s + 3),
r[s + 0] = char(values[i] >> 12 | 0xe0),
r[s + 1] = char(values[i] >> 6 & 0x3f | 0x80),
r[s + 2] = char(values[i] & 0x3f | 0x80),
s += 3;
else
r = (char *) realloc(r, s + 4),
r[s + 0] = char(values[i] >> 18 | 0xf0),
r[s + 1] = char(values[i] >> 12 & 0x3f | 0x80),
r[s + 2] = char(values[i] >> 6 & 0x3f | 0x80),
r[s + 3] = char(values[i] & 0x3f | 0x80),
s += 4;
}
return r;
}
};

最佳答案

ustring 的析构函数在哪里?它不应该释放分配的内存吗?


让我们看看例如在赋值运算符处:

ustring operator=(ustring input)
{
ustring result(input);
...
return *this;
}

您按值传递一个 ustring 参数。这可能会导致通过复制构造函数创建一个拷贝。您再次调用复制构造来初始化 result。我怀疑当您将 *this 作为 ustring 返回时(再次按值而不是按引用),您又调用了复制构造。

让我们看一下这三种情况中的一种,即result:当这个局部变量超出范围时(即在函数结束时),它会被自动销毁。但是,如果您不提供一个析构函数 (~ustring) 来释放分配的内存,就会发生内存泄漏。

并且由于您显然有大量的复制构造和按值传递而没有析构函数来释放分配的内存,因此您将获得很多很多未释放的内存。


此外:为什么使用mallocfree而不是new[]delete[]? 您可以摆脱丑陋的 sizeof(int) * ... 计算和 (int*) 类型转换。而不是:

values = (int *) malloc(sizeof(int) * len);

你只需写:

values = new int[len];

关于c++ - 内存没有被释放,导致巨大的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2753228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com