C ++如何解决我的内存泄漏
c++ how to solve my memory leak?
考虑整数的二进制类表示的以下含义:
class Binary {
private:
int *digits;
int first1;
public:
Binary() {
digits = new int[128];
digits[0]=0;
first1=0;
}
~Binary() {
cout<<"deleting"<<endl;
delete [] digits;
}
Binary(const Binary& b){
digits = new int[128];
memcpy(digits,b.digits,128*sizeof(int));
first1=b.first1;
}
explicit Binary(double x){
int n=(int)x,i;
digits = new int[128];
for (i=0; n ; i++,n>>=1) digits[i]=(n & 1)? 1:0;
first1=i-1;
}
Binary& operator =(const Binary& b){
if (this==&b) return *this;
memcpy(digits,b.digits,128*sizeof(int));
first1=b.first1;
return *this;
}
Binary(int n) {
int i;
digits = new int[128];
for (i=0; n ; i++,n>>=1) digits[i]=(n & 1)? 1:0;
first1=i-1;
}
void print() {
for (int i=first1; i>=0 ; i--) cout<<digits[i];
cout<<endl;
}
operator int() {
int x = 1,sum=0;
for (int i=0; i<=first1 ; i++,x<<=1) sum+=digits[i]*x;
return sum;
}
Binary& operator +(Binary& a) {
int overflow = 0;
Binary* b1=new Binary();
int max = a.first1>this->first1? a.first1 : this->first1,bit;
for (int i=0; i<=max ; i++) {
bit=a.digits[i]+this->digits[i]+overflow;
overflow=0;
if (bit>1) overflow=1;
b1->digits[i]=bit%2;
}
return *b1;
}
};
以及使用它的主要内容:
int main() {
Binary b(91);
int x=9;
Binary *b2=new Binary();
*b2=b+x;
x=*b2;
b2->print();
cout<<" = "<<x;
cin>>x;
}
让我们谈谈这条线:
*b2=b+x;
首先,编译器为 int x 隐式分配一个新的二进制实例,然后将其用作加法的参数,然后为加法结果创建一个新的二进制实例,并将其逐位复制到 *B2。
问题是,如果您运行此代码,它只会打印删除一次,而为执行命令创建了 2 个对象。 显然,加法代码存在泄漏,其中我显式创建了一个新对象来返回结果。
Q1:我说的对吗?
Q2:我能做些什么来克服这个问题?
编辑:有关运算符重载主题的答案和更多信息可以在这里找到
摘要:分配了new
的对象必须使用 delete
删除。 使用 new[]
分配的对象必须使用 delete[]
删除。 全局变量和局部变量在其作用域/TU 执行结束时会自动删除。 在Binary& operator +(Binary& a)
中,你做了一个泄漏的Binary
,在main
你做了另一个泄露的Binary
。
如果这样写operator+
,这些问题就可以避免:
Binary operator +(Binary& a) const{ //return by value
Binary b1(*this); //hold it on the stack
//math here
return b1; //return by value
}
如果主要情况下您也避免了分配:
Binary b2 = b+x;
x = b2;
b2.print();
这将比您的原始代码更快,更容易阅读和理解,并且不会泄漏。
[其他注意事项]
对内部数据使用std::vector
,而不是管理自己的动态数组。 vector
更容易,也不太可能犯错误。
通常,最好尽可能明确地进行转化(例如int
-> Binary
)。 它增加了打字,但省去了麻烦。 这也适用于您的int
转换运算符。
函数常量。 现在,如果你得到一个const Binary
,你几乎不能用它做任何事情。 你不能打印它,你不能添加任何东西...
您似乎每int
存储一位,这意味着您使用的空间比需要的多 97%(浪费了 99.999999995% 的值),这太愚蠢了。 大多数新手从每char
0-9
开始,这只浪费了50%的空间。(虽然这仍然是 96% 的值),但真的很容易理解。
正常的加法方法是这样的:
Binary& operator+=(const Binary& rhs) {
int max = a.first1>this->first1? a.first1 : this->first1,bit;
for (int i=0; i<=max ; i++) {
bit=a.digits[i]+this->digits[i]+overflow;
overflow=0;
if (bit>1) overflow=1;
b1->digits[i]=bit%2;
}
}
Binary friend operator+(Binary lhs, const Binary& rhs) {
{return lhs+=rhs;}
如果你真的只看到"删除"一次,那么这一定是变量b。 *b2 = b+x
可以通过将 b 转换为 int,添加 x,从中构造一个二进制并将其复制到 b2 指向的位置来完成。由于 b2 只是一个原始指针,因此您正在泄漏初始 *b2 实例和覆盖它的实例。
你不会在 main 的末尾删除 b2。
此外,运算符应按值返回,而不是返回分配的二进制对象,因为这会泄漏C++因为没有垃圾回收
运算符 + 也应该采用常量引用。
此外,print、operator+ 和operator int 应该是 const 成员函数
此外,您不需要动态分配 128 个整数,只需将其设为 128 个整数的数组即可
private:
int digits[128];
并删除数字上的删除
此外,您应该在构造函数中初始化它
memset(digits, 0, sizeof(digits));
- 为什么我可以使用比分配的内存更多的内存
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 为什么我只能在C++中使用可变长度数组分配小于 10 mb 的内存?
- 为什么我能够为阵列分配比计算机实际拥有的内存更多的内存
- 无法找出我的代码中的内存泄漏
- 我是否需要在 c++ 中从本地指针中释放分配的内存?
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 我的堆栈弹出式磁带的实现是否泄漏内存?
- 当注入程序的内存空间时,如何读取从 0 到 0xFFFFFFFFF 的每个字节?我正在创建模式扫描仪
- 使用 valgrind 检查我的链表暗示中的内存泄漏,让我"肯定丢失:1 个块中有 40 个字节"
- 在我的以下代码中获取 MLE(内存限制错误).尝试解决 ROUND C 2019(问题 A-摆动行走)启动问题
- 如果我在 c++ 中以 new 的放置形式使用没有足够的内存,会发生什么情况?
- 为什么 valgrind 报告两个内存分配,而我的代码只请求一个?
- 为什么我无法获取 MSVS2019 / C++ 中字符或uint8_t变量的内存地址?
- 我的内存泄漏是由循环引用引起的吗?
- 找不到我的内存泄漏
- C ++如何解决我的内存泄漏
- 如何加快我的内存扫描程序
- 是什么导致我的内存泄漏与OpenCV
- 修复了我的内存泄漏,我不明白为什么它有效