在哪些情况下,虚拟基类析构函数仍然可以不调用,从而导致内存泄漏
In what cases the virtual base destructor can still go uncalled causing memory leaks?
有一个基类Heap
和两个派生类MinHeap
和MaxHeap
-如下所示:
我创建了一个派生类对象:
MinHeap* myminheap = new MinHeap();
但是使用
删除它delete myminheap;
带/不带virtual ~Heap() {}
给我glibc内存泄漏错误!关键是什么?我已经浏览了很多关于这个的帖子.....
在派生类
中重写new/delete操作符为什么在删除派生类对象时调用基类析构函数(virtual) ?
删除带有基类指针的派生类时的内存泄漏…但我不明白为什么设置基析构函数虚拟仍然会导致内存错误?
Heap* h_ptr = myminheap;
delete h_ptr;
p。做^事情是不可能的,我不能将派生类对象指针类型转换为基指针,因为会弹出以下错误
‘class Heap’ has no member named ‘insert’
‘class Heap’ has no member named ‘pop_min'
我可以通过在Heap
类
后来,我意识到,如果我调用free(h_ptr);
,而不是调用delete h_ptr;
,我不会受到内存泄漏。华友世纪!但是我需要一些关于这种行为的启示!
heap.h
#include <cstdlib>
#include <vector>
#include <iterator>
using namespace std;
class Heap
{
public:
Heap() {}
~Heap() {}
vector <int> heap;
int left(int parent);
int right(int parent);
int parent(int child);
int size() {return heap.size();}
virtual void insert(int element) {}
virtual int pop_min() {}
virtual int pop_max() {}
void print();
};
class MinHeap : public Heap
{
private:
void heapify_up(int index);
void heapify_down(int index);
public:
MinHeap() {}
~MinHeap() {}
int pop_min();
void insert(int element);
};
class MaxHeap : public Heap
{
private:
void heapify_up(int index);
void heapify_down(int index);
public:
MaxHeap() {}
~MaxHeap() {}
int pop_max();
void insert(int element);
};
heap.cc
#include <cstdlib>
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
#include "heap.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int Heap::left(int parent)
{
int i = (parent << 1) + 1; //2 * parent + 1 read more on bit shifts
return (i < heap.size()) ? i : -1;
}
int Heap::right(int parent)
{
int i = (parent << 1) + 2;
return (i < heap.size()) ? i : -1;
}
int Heap::parent(int child)
{
if(child){
int i = (child >> 1) - 1;
return i;
}
else return -1;
}
void Heap::print()
{
vector<int>::iterator i = heap.begin();
cout << "Heap = ";
while(i != heap.end()){
cout << *i << " ";
i++;
}
cout << endl;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MinHeap::pop_min()
{
int min = heap.front();
heap[0] = heap[heap.size() - 1];
heap.pop_back();
heapify_down(0);
return min;
}
void MinHeap::insert(int element)
{
heap.push_back(element);
heapify_up(heap.size() - 1);
}
void MinHeap::heapify_up(int index)
{
while(index > 0 && parent(index) >= 0 && heap[parent(index)] > heap[index]){
int temp = heap[index];
heap[index] = heap[parent(index)];
heap[parent(index)] = temp;
index = parent(index);
}
}
void MinHeap::heapify_down(int index)
{
int child = left(index);
if(child > 0 && right(index) > 0 && heap[child] > heap[right(index)])
child = right(index);
if(heap[index] > heap[child]){
int temp = heap[child];
heap[child] = heap[index];
heap[index] = temp;
heapify_down(child);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MaxHeap::pop_max()
{
int max = heap.front();
heap[0] = heap[heap.size() - 1];
heap.pop_back();
heapify_down(0);
return max;
}
void MaxHeap::insert(int element)
{
heap.push_back(element);
heapify_up(heap.size() - 1);
}
void MaxHeap::heapify_up(int index)
{
while(index > 0 && parent(index) >= 0 && heap[parent(index)] < heap[index]){
int temp = heap[index];
heap[index] = heap[parent(index)];
heap[parent(index)] = temp;
index = parent(index);
}
}
void MaxHeap::heapify_down(int index)
{
int child = left(index);
if(child > 0 && right(index) > 0 && child < right(index))
child = right(index);
if(heap[index] < heap[child]){
int temp = heap[child];
heap[child] = heap[index];
heap[child] = temp;
heapify_down(child);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// test program
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main(){
// Create the heap
MinHeap* myminheap = new MinHeap();
myminheap->insert(700);
myminheap->print();
myminheap->insert(500);
myminheap->print();
myminheap->insert(100);
myminheap->print();
myminheap->insert(800);
myminheap->print();
myminheap->insert(200);
myminheap->print();
myminheap->insert(400);
myminheap->print();
myminheap->insert(900);
myminheap->print();
myminheap->insert(1000);
myminheap->print();
myminheap->insert(300);
myminheap->print();
myminheap->insert(600);
myminheap->print();
// Get priority element from the heap
int heapSize = myminheap->size();
for ( int i = 0; i < heapSize; i++ )
cout << "Get min element = " << myminheap->pop_min() << endl;
// Cleanup
delete myminheap;
return 1;
}
如果您新建了一个MinHeap,那么您就不能通过调用Heap类型的free来删除它。您的问题是,您正在存储指向对象的指针,并说它是另一回事,因此delete例程不知道您正在尝试删除MinHeap,并且只删除Heap部分(大致)。
你可以直接在myminheap对象上调用delete,这应该可以工作。
一个更好的解决方案是根本不在堆上创建MinHeap,而是在堆栈上创建它,并且不使用任何指针。如果出于某种原因需要在堆上创建它,可以在智能指针类中创建它,例如使用shared_ptr<>,这将极大地帮助您。
相关文章:
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 为什么调用堆栈数组会导致内存泄漏
- 调用析构函数以释放动态分配的内存
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 指向数组unique_ptr在调用 release() 后会自动释放动态内存,这是真的吗?
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 调用std::函数成员时内存损坏
- 对外部函数的调用是否强制从内存加载
- C++ 在不释放内存的情况下调用析构函数
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- ActiveMQ使用者的内存使用量在onMessage调用后不断增加
- 为什么创建进程 API 调用会导致内存访问冲突?
- 分配内存并在回调时调用C++的 Rust 函数崩溃
- 从 JNI 调用的 DLL 从哪里获取其内存以进行分配,例如 Malloc
- 在使用新操作员和C 中的结构的调用构造函数时,获得内存损坏(Malloc)
- 调用 shmdt() 后无法删除共享内存段
- 正在调用内存中对象的虚拟函数