您好,我有一个关于 C++ 内存管理的一般查询。 在这个程序的帮助下,我只知道 new 用于在堆上分配内存,临时变量在堆栈上分配内存。如果我们在堆上分配内存,我们也必须手动释放它,否则会发生内存泄漏.
但在程序中,我通过在堆上创建 BST 类型的新变量 temp 来更新名为 Insert 的函数中的 BST 结构对象。但是我不确定如何释放该内存。如果我使用 free 命令在函数的末尾,即 free(temp) 然后存储在该内存中的值将丢失,如果我再次尝试访问它,我将收到错误消息,而且我当然不能在 main 中使用 free(temp) 因为它不是main 的局部变量。 谁能告诉我应该怎么做。
顺便说一句,我必须提到,在不使用 free(temp) 的情况下,我的程序也能正常工作,但我猜想发生了内存泄漏,这很糟糕。
我也有点困惑,为什么我的程序运行没有错误,如果我注释析构函数 ~BST()
但是当我取消注释时给出链接器错误。
#include<iostream>
#include<string>
#include<conio.h>
#include<array>
#include<stack>
#include<sstream>
#include<algorithm>
#include<vector>
#include<ctype.h>//isdigit
#include<deque>
#include<queue>
#include<map>
using namespace::std;
struct BST
{
int data;
BST *left;
BST *right;
BST(int d,struct BST* l,BST *r):data(d) , left(l) ,right(r)
{
}
BST()
{
}
//~BST();
};
void levelOrder(struct BST *root)
{
struct BST *temp=NULL;
int count =0;
deque<struct BST*> dq;
if(!root)
{
return;
}
dq.push_back(root);
count=dq.size();
while(!dq.empty())
{
temp=dq.front();
cout<<temp->data<<" ";
if(temp->left)
{
dq.push_back(temp->left);
}
if(temp->right)
{
dq.push_back(temp->right);
}
dq.pop_front();
if(--count==0)
{
cout<<endl;
count=dq.size();
}
}
}
void Insert(struct BST*root,int data)
{
//struct BST temp(data,NULL,NULL);
BST *temp = new BST(data,NULL,NULL);
temp->data =data;
temp->left= NULL;
temp->right=NULL;
if(!root)
{
return;
}
while(root)
{
if((root)->data >data)
{
(root)=(root)->left;
if(!(root)->left)
{
(root)->left=temp;
break;
}
}
else
{
(root)=(root)->right;
if(!(root)->right)
{
(root)->right=temp;
break;
}
}
}
}
int main()
{
deque<struct BST> dq1,dq2;
BST e(4,NULL,NULL);
BST f(3,NULL,NULL);
BST d(1,&f,NULL);
BST b(2,&d,&e);
BST c(8,NULL,NULL);
BST a(6,&b,&c);
levelOrder(&a);
Insert(&a,5);
cout<<a.left->right->right->data;
cout<<endl;
levelOrder(&a);
_getch();
return 0;
}
最佳答案
首先,在 C++ 中,您通常应该使用 new
和 delete
(他们称 ctors/dtors 等)对于数组,使用 delete[]
. new
/delete
与 malloc
不兼容/free
.
我猜 BST 是一个二叉搜索树。所以你有一个动态分配内存的树。
您必须释放整棵树,这意味着您也应该按顺序执行,以免出现悬挂指针。
可以通过确保 BST 节点始终空闲其子节点来显着降低复杂性。然后当你删除根节点时,它会递归地删除所有其他节点。
在我看来,最简单的方法是使用智能指针,例如 shared_ptr<T>
, unique_ptr<T>
或 auto_ptr
(最后一个有警告,但我不会在这里解决它们。)
结构如下所示:
struct BST
{
/* ctor, dtor omitted for brevity. */
std::unique_ptr<BST> left;
std::unique_ptr<BST> right;
}
您的 BST 节点超出范围,即您 delete
它,或者它被分配在堆栈上并且代码退出 block 。 left 和 right 的析构函数被调用并且 unique_ptr
实现确保调用 delete
在它存储的指针上。
关于c++ - C++内存管理相关查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15180403/