内存泄漏和多态性
Memory leak and polymorphism
我一直试图在C++中围绕多态性进行思考 据我了解,它是这样的
class Base {
//...
public:
virtual int Foo() {...} = 0;
};
//...
class Derived: public Base { //Could be protected or private as well
//...
public:
int Foo() {...}
};
我还知道,当我们有一个动态分配对象的数组时,我们必须在删除数组的每个单独条目后在程序结束时调用 delete [] arr。
所以当我运行以下程序时,我不确定为什么会出现内存泄漏
#include <iostream>
using namespace std;
class Number {
public:
~Number() {
cout << "Expression deleted" << endl;
}
virtual void print() = 0;
};
class Int: public Number {
private:
int num;
public:
Int(int n) {
num = n;
}
void print() {
cout << "Num: " << num << endl;
}
~Int() {
cout << "Number deleted" << endl;
}
};
int main() {
Number *arr[10];
arr[0] = new Int(1);
arr[1] = new Int(2);
arr[2] = new Int(3);
arr[0]->print();
arr[1]->print();
arr[2]->print();
delete arr[0];
delete arr[1];
delete arr[2];
delete [] arr;
}
编译时首先给我一个警告
poly.cc: In function 'int main()':
poly.cc:37:12: warning: deleting array 'Number* arr [10]' [enabled by default]
然后当我运行它时,它给了我这个
Num: 1
Num: 2
Num: 3
Expression deleted
Expression deleted
Expression deleted
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x00007fff785732d0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7db26)[0x7f9274641b26]
./a.out[0x400b07]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f92745e576d]
./a.out[0x400959]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:32 43144247
00601000-00602000 r--p 00001000 00:32 43144247
00602000-00603000 rw-p 00002000 00:32 43144247
01b5f000-01b91000 rw-p 00000000 00:00 0 [heap]
7f92740b1000-7f92740c7000 r-xp 00000000 fc:00 50593804 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f92740c7000-7f92742c6000 ---p 00016000 fc:00 50593804 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f92742c6000-7f92742c7000 r--p 00015000 fc:00 50593804 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f92742c7000-7f92742c8000 rw-p 00016000 fc:00 50593804 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f92742c8000-7f92743c3000 r-xp 00000000 fc:00 50602224 /lib/x86_64-linux-gnu/libm-2.15.so
7f92743c3000-7f92745c2000 ---p 000fb000 fc:00 50602224 /lib/x86_64-linux-gnu/libm-2.15.so
7f92745c2000-7f92745c3000 r--p 000fa000 fc:00 50602224 /lib/x86_64-linux-gnu/libm-2.15.so
7f92745c3000-7f92745c4000 rw-p 000fb000 fc:00 50602224 /lib/x86_64-linux-gnu/libm-2.15.so
7f92745c4000-7f9274778000 r-xp 00000000 fc:00 50602238 /lib/x86_64-linux-gnu/libc-2.15.so
7f9274778000-7f9274977000 ---p 001b4000 fc:00 50602238 /lib/x86_64-linux-gnu/libc-2.15.so
7f9274977000-7f927497b000 r--p 001b3000 fc:00 50602238 /lib/x86_64-linux-gnu/libc-2.15.so
7f927497b000-7f927497d000 rw-p 001b7000 fc:00 50602238 /lib/x86_64-linux-gnu/libc-2.15.so
7f927497d000-7f9274982000 rw-p 00000000 00:00 0
7f9274982000-7f9274a84000 r-xp 00000000 fc:00 41962840 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f9274a84000-7f9274c83000 ---p 00102000 fc:00 41962840 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f9274c83000-7f9274c8b000 r--p 00101000 fc:00 41962840 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f9274c8b000-7f9274c8d000 rw-p 00109000 fc:00 41962840 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f9274c8d000-7f9274c90000 rw-p 00000000 00:00 0
7f9274c90000-7f9274cb2000 r-xp 00000000 fc:00 50602228 /lib/x86_64-linux-gnu/ld-2.15.so
7f9274e84000-7f9274e89000 rw-p 00000000 00:00 0
7f9274eae000-7f9274eb2000 rw-p 00000000 00:00 0
7f9274eb2000-7f9274eb3000 r--p 00022000 fc:00 50602228 /lib/x86_64-linux-gnu/ld-2.15.so
7f9274eb3000-7f9274eb5000 rw-p 00023000 fc:00 50602228 /lib/x86_64-linux-gnu/ld-2.15.so
7fff78553000-7fff78574000 rw-p 00000000 00:00 0 [stack]
7fff785c7000-7fff785c9000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
似乎已成功添加和删除对象。我看不出有什么问题。
这里有两个问题。首先,这是无效的:
delete [] arr;
arr
不是new[]
-ed,所以不需要delete[]
-ed。 arr
只是在堆栈上。这就是编译器给你警告的原因!(叮当直错误)。好的经验法则是不要忽略编译器警告。
第二个问题在这里:
~Number() {
cout << "Expression deleted" << endl;
}
当您delete
Number
时,将执行~Number()
,并且该内存将被释放...但不是~Int()
.如果要删除基类指针,也需要使析构函数virtual
。这也应该导致警告,例如:
main.cpp: In function 'int main()':
main.cpp:37:14: warning: deleting object of abstract class type 'Number' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete arr[0];
^
因为对于每个多调类,您都需要定义一个虚拟析构函数。否则,通过指向基类的指针删除派生类不会调用派生类析构函数。
相关文章:
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 具有数字集C++的多态性中的内存泄漏
- 内存泄漏和多态性
- 使多态性在C++映射中工作,而不会发生内存泄漏
- 多态性=资源泄漏中基类缺少虚拟析构函数
- 使用指示器的c++和Java之间SWIG多态性中的内存泄漏