最近写了一个小程序,代码如下,功能是求一个树的重心被选中时所对应的子树中节点个数中最大值的最小值。
首先看错误代码,该代码可以正常跑出结果,问题在内存释放上。
/*
树的重心
*/
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iterator>
#include<cassert>
using namespace std;
typedef struct adjEdge{//表示邻接边信息
int index;//节点的下表索引
bool visit;//该index的节点是否被访问
int weight;//边的权值
struct adjEdge *next;//下一个
}adjEdge,*PadjEdge;
typedef struct Head{
adjEdge *first;
}head,*Phead;
using Vchar = vector<char>;
using V_adjEdge = vector<Phead>;
/*
* 树的节点信息存在一个数组中,并且与下标对应
* a b c d e f
* 0 1 2 3 4 5
*/
int N = 0,ans = 0xfffffff;
int dfs(V_adjEdge& adj,int i,vector<bool>& vi){
//进行树重心的查找
assert(i>0);
vi[i] = true;
int size = 0;//size记录u的最大子树的节点数。假设u为重心
int sum = 1;//sum为以u为根节点的子树的节点数
PadjEdge p = adj[i]->first;
while(p){
int j = p->index;
if(vi[j]){
p = p->next;
continue;
}
int s = dfs(adj,j,vi);
size = max(s,size);
sum += s;
}
ans = min(ans,max(size,N-sum));
return sum;
}
void myfree(V_adjEdge& v){
//释放内存
for(size_t i = 1;i < v.size();++i){
Phead p = v[i];
PadjEdge q = p->first;
free(p);
p = nullptr;
while(q){
PadjEdge temp = q;
q = q->next;
free(temp);
temp = nullptr;
}
}
}
int main(){
int num;//节点的个数
cin>>num;
N = num;
vector<bool> visit(num+1,false);
Vchar node(num+1);//保存节点信息,第一个位置预留,没用
V_adjEdge Adjlist(num);//邻接链表信息
//问题出在这,此处使用了malloc进行动态内存分配,上面的myfree函数没有问题,可以正常释放。
for(int i = 1;i<num+1;++i){
Phead h = (Phead)malloc(sizeof(head));
h->first = nullptr;
Adjlist[i] = h;
}
for(int i = 1;i<num;++i){
int from,to;
cin>>from>>to;
PadjEdge p = (PadjEdge)malloc(sizeof(adjEdge));
p->index = to;
p->weight = 0;
p->visit = false;
p->next = Adjlist[from]->first;
Adjlist[from]->first = p;
}
int x = dfs(Adjlist,1,visit);//此处的x没有使用
cout<<ans<<endl;
myfree(Adjlist);
// system("pause");
return 0;
}
问题:从第六行开始往下的那个for循环,因为vector预先是想去保存指针变量,所以一般要么用malloc要么用new,我这里用的是malloc,但是这样会出问题,会在return 0执行前,会去调用vector的析构函数,会在::delete(__p)处报异常。
解决办法: 将for里面改为new申请就可以,具体原因暂不明。
修改后的代码块:
for(int i = 1;i<num+1;++i){
Phead h = new head;
h->first = nullptr;
Adjlist[i] = h;
}
如有哪位大佬知道原因,还请留言指教,先行感谢!!!