c++ delete[]:怎么知道需要释放的空间大小

今天想到了这个问题,开始以为和数组一样,要在同一个作用域内才能知道释放多少空间:

#include "iostream"
using namespace std;

class A{
	int static i;
public:
	A(){}
	~A(){cout<<"释放第"<<++i<<"个对象"<<endl;};
};
int A::i = 0;

int main(){
	A *f = new A[11];
	delete[] f;
	return 0;
}

这样会释放11个对象。

但是下面这样不在同一个作用域它也能释放掉11个对象:

#include "iostream"
using namespace std;

class A{
	int static i;
public:
	A(){}
	~A(){cout<<"释放第"<<++i<<"个对象"<<endl;};
};
int A::i = 0;


A* test(){
	return new A[11];
}


int main(){
	A *f = test();
	delete[] f;
	return 0;
}

很好奇这个时候main函数是怎么知道要释放11个对象的空间的呢?因为test函数只是返回了一个指针,并没有返回申请空间大小的信息。去搜索了一下,原来会在申请的空间首位置之前的4个字节内记录申请了多少空间(可以理解为数组下标为-1的位置,但是这样理解并不总是正确):

#include "iostream"
using namespace std;

class A{
	int static i;
public:
	A(){}
	~A(){cout<<"释放第"<<++i<<"个对象"<<endl;};
};
int A::i = 0;


A* test(){
	return new A[11];
}

int main(){
	A *f = test();
	//获取申请空间头部之前的4字节地址
	int addr = (int)f - 4;
	//输出该4字节空间里面存储的内容
	cout<<"即将释放"<<*(int *)addr<<"个对象:"<<endl;
	delete []f;
	return 0;
}	

下面的程序做了3种情况的测试。同时对每个对象加了个ID,通过输出会发现释放的顺序是从数组尾端往前端释放,即先申请的后释放。

#include "iostream"
using namespace std;

class A{
	int static i;
	int static j;
public:
	int myID;
	A():myID(j++){}
	~A(){cout<<"释放第"<<++i<<"个对象"<<";其标号为"<<myID<<endl;};
};
int A::i = 0;
int A::j = 0;


A* test(){
	return new A[11];
}

int main(){
	//测试一:
	//只申请一个的情况,由于只释放一个,所以前四字节值无意义
	A *f = new A;
	//获取申请空间头部之前的4字节地址
	int addr = (int)f - 4;
	//输出该4字节空间里面存储的内容
	cout<<"用new申请空间,前四字节值无意义:"<<*(int *)addr<<endl;
	delete f;
	cout<<endl;

	//测试二:
	//更改4字节空间里面的值为5,那么就只会释放5个对象
	f = test();
	//获取申请空间头部之前的4字节地址
	addr = (int)f - 4;
	//更改该4字节空间里面的值
	*(int *)addr = 5;
	//输出该4字节空间里面存储的内容
	cout<<"即将释放"<<*(int *)addr<<"个对象:"<<endl;
	delete []f;
	cout<<endl;

	//测试三:	
	//更改4字节空间里面的值为20,那么就会释放20个对象.后面内存按照A类型的内存布局进行解释
	//(当然多余的空间要保证能读写,比如把20改为2000很可能就跑到其他程序的空间里面去了,这个时候程序就崩溃了)
	f = test();
	//获取申请空间头部之前的4字节地址
	addr = (int)f - 4;
	//更改该4字节空间里面的值
	*(int *)addr = 20;
	//输出该4字节空间里面存储的内容
	cout<<"即将释放"<<*(int *)addr<<"个对象:"<<endl;
	delete []f;

	return 0;
}	



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值