C++ 在什么情况下,虚拟基析构函数仍然可以不调用,从而导致内存泄漏?
有一个基类C++ 在什么情况下,虚拟基析构函数仍然可以不调用,从而导致内存泄漏?,c++,memory-leaks,free,C++,Memory Leaks,Free,有一个基类Heap和两个派生类MinHeap和MaxHeap——如下所示: 我创建一个派生类对象,如下所示: MinHeap* myminheap = new MinHeap(); 但是使用 delete myminheap; 有/没有virtual~Heap(){}会给我glibc内存泄漏错误! 关键是什么? 我看过很多关于这个的帖子 。。。。但我无法理解为什么将基本析构函数设置为虚拟仍然会导致内存错误 Heap* h_ptr = myminheap; delete h_ptr;
Heap
和两个派生类MinHeap
和MaxHeap
——如下所示:
我创建一个派生类对象,如下所示:
MinHeap* myminheap = new MinHeap();
但是使用
delete myminheap;
有/没有virtual~Heap(){}
会给我glibc内存泄漏错误!
关键是什么?
我看过很多关于这个的帖子
。。。。但我无法理解为什么将基本析构函数设置为虚拟仍然会导致内存错误
Heap* h_ptr = myminheap;
delete h_ptr;
ps.不可能执行^操作,我无法将派生类对象指针类型转换为基指针,因为会弹出以下错误
‘class Heap’ has no member named ‘insert’
‘class Heap’ has no member named ‘pop_min'
我可以通过在堆
类中引入它们来解决这个问题
后来,我意识到与其调用delete h_ptr代码>如果我呼叫免费(h_ptr)代码>我没有受到内存泄漏的影响。。
万岁!但是我需要一些关于这种行为的信息
堆
#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);
};
#包括
#包括
#包括
使用名称空间std;
类堆
{
公众:
堆(){}
~Heap(){}
向量堆;
int左(int父级);
int-right(int-parent);
int父代(int子代);
int size(){返回heap.size();}
虚空插入(int元素){}
虚拟整数pop_min(){}
虚拟整数pop_max(){}
作废打印();
};
类MinHeap:公共堆
{
私人:
void heapify_up(整数索引);
void heapify_down(整数索引);
公众:
MinHeap(){}
~MinHeap(){}
int pop_min();
无效插入(int元素);
};
类MaxHeap:公共堆
{
私人:
void heapify_up(整数索引);
void heapify_down(整数索引);
公众:
MaxHeap(){}
~MaxHeap(){}
int pop_max();
无效插入(int元素);
};
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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
#包括“heap.h”
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int Heap::left(int父级)
{
int i=(父1)-1;
返回i;
}
否则返回-1;
}
无效堆::打印()
{
向量::迭代器i=heap.begin();
cout 0&&right(索引)>0&&heap[child]>heap[right(索引)])
child=右(索引);
if(堆[索引]>堆[子]){
int temp=堆[子];
堆[子]=堆[索引];
堆[索引]=temp;
健康(儿童);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MaxHeap::pop_max()
{
int max=heap.front();
heap[0]=heap[heap.size()-1];
heap.pop_back();
heapify_down(0);
返回最大值;
}
void MaxHeap::insert(int元素)
{
堆。推回(元素);
heapify_up(heap.size()-1);
}
void MaxHeap::heapify_up(int索引)
{
而(索引>0&&parent(索引)>=0&&heap[parent(索引)]0&&right(索引)>0&&childinsert(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();
//从堆中获取优先级元素
int-heapSize=myminheap->size();
for(int i=0;i cout如果你新建了一个MinHeap,那么你就不能通过调用堆类型的free来删除它。你的问题是,你存储了一个指向该对象的指针,并说它是另一个东西,因此delete例程不知道你在试图删除一个MinHeap,而只删除堆部分(大致上)
您可以直接调用myminheap对象上的delete,这应该可以工作
更好的解决方案是根本不在堆上创建MinHeap,而是在堆栈上创建它,并在没有任何指针的情况下使用它。如果出于某种原因需要在堆上创建它,请改为在智能指针类中创建它,例如使用shared_ptr,这将极大地帮助您。您不能混合使用new
和free
。这些代码看起来很好。你是如何使用它的?确切的错误信息是什么(或者,如果没有这样的信息,你会怎么想,有泄漏)?总是调用虚拟析构函数。你的问题在别处。发布一个复制错误的完整示例。这根本不意味着内存泄漏。发布代码,说明如何使用该类。虽然我觉得这是不可能的,但我也尝试了它,以防万一。调用虚拟析构函数,没有错误,等等。编辑:完整代码现在发布。。完整的代码没有显示这一点,但是第一次它显示了一个new
,然后是一个free
,所以我不清楚这是同一个崩溃的代码。@ShafikYaghmournew
之后是delete
,正如现在更新的post中显示的那样,后面是new
free
没有错误弹出..注意:我尝试的free
修改是在上面完整的代码之前提到的