vector的动态分配内存实验

vector的插入和删除伴随着大量的数据拷贝(移动)


#include <vector>
#include <iostream>

using namespace std;

int main()
{
	vector<int> vData;
	constexpr int SIZE = 50;

	cout << "..........分配过程................" << endl;
	for (int i = 0; i < SIZE; ++i)
	{
		vData.push_back(i);
		cout << "ptr" << i << "=" << &vData[i] << endl;
	}
	
	cout << "..........分配完成...................." << endl;
	for (int i = 0; i < SIZE; ++i)
	{
		cout << "ptr" << i << "=" << &vData[i] << endl;
	}

	cout << "..........删除过程..................." << endl;
	for (auto it= vData.begin(); it!=vData.end(); ++it)
	{
		static int i = 0;
		if (i < 20)
		{
			vData.erase(it);
		}
		
		cout << "ptr" << i << "=" << &vData[i] << endl;
		++i;
	}

	cout << "..........删除完成..................." << endl;
	for (int i = 0; i < vData.size(); ++i)
	{
		cout << "ptr" << i << "=" << &vData[i] << endl;
	}
	return 0;
}


实验结果

..........分配过程................
ptr0=011694D0
ptr1=01169414
ptr2=01164238
ptr3=011653D4
ptr4=01164240
ptr5=01164244
ptr6=011653E0
ptr7=011653E4
ptr8=011653E8
ptr9=0116541C
ptr10=01165420
ptr11=01165424
ptr12=01165428
ptr13=01164F34
ptr14=01164F38
ptr15=01164F3C
ptr16=01164F40
ptr17=01164F44
ptr18=01164F48
ptr19=0116508C
ptr20=01165090
ptr21=01165094
ptr22=01165098
ptr23=0116509C
ptr24=011650A0
ptr25=011650A4
ptr26=011650A8
ptr27=011650AC
ptr28=01165248
ptr29=0116524C
ptr30=01165250
ptr31=01165254
ptr32=01165258
ptr33=0116525C
ptr34=01165260
ptr35=01165264
ptr36=01165268
ptr37=0116526C
ptr38=01165270
ptr39=01165274
ptr40=01165278
ptr41=0116527C
ptr42=0116E600
ptr43=0116E604
ptr44=0116E608
ptr45=0116E60C
ptr46=0116E610
ptr47=0116E614
ptr48=0116E618
ptr49=0116E61C
..........分配完成....................
ptr0=0116E558
ptr1=0116E55C
ptr2=0116E560
ptr3=0116E564
ptr4=0116E568
ptr5=0116E56C
ptr6=0116E570
ptr7=0116E574
ptr8=0116E578
ptr9=0116E57C
ptr10=0116E580
ptr11=0116E584
ptr12=0116E588
ptr13=0116E58C
ptr14=0116E590
ptr15=0116E594
ptr16=0116E598
ptr17=0116E59C
ptr18=0116E5A0
ptr19=0116E5A4
ptr20=0116E5A8
ptr21=0116E5AC
ptr22=0116E5B0
ptr23=0116E5B4
ptr24=0116E5B8
ptr25=0116E5BC
ptr26=0116E5C0
ptr27=0116E5C4
ptr28=0116E5C8
ptr29=0116E5CC
ptr30=0116E5D0
ptr31=0116E5D4
ptr32=0116E5D8
ptr33=0116E5DC
ptr34=0116E5E0
ptr35=0116E5E4
ptr36=0116E5E8
ptr37=0116E5EC
ptr38=0116E5F0
ptr39=0116E5F4
ptr40=0116E5F8
ptr41=0116E5FC
ptr42=0116E600
ptr43=0116E604
ptr44=0116E608
ptr45=0116E60C
ptr46=0116E610
ptr47=0116E614
ptr48=0116E618
ptr49=0116E61C
..........删除过程...................
ptr0=0116E558
ptr1=0116E55C
ptr2=0116E560
ptr3=0116E564
ptr4=0116E568
ptr5=0116E56C
ptr6=0116E570
ptr7=0116E574
ptr8=0116E578
ptr9=0116E57C
ptr10=0116E580
ptr11=0116E584
ptr12=0116E588
ptr13=0116E58C
ptr14=0116E590
ptr15=0116E594
ptr16=0116E598
ptr17=0116E59C
ptr18=0116E5A0
ptr19=0116E5A4
ptr20=0116E5A8
ptr21=0116E5AC
ptr22=0116E5B0
ptr23=0116E5B4
ptr24=0116E5B8
ptr25=0116E5BC
ptr26=0116E5C0
ptr27=0116E5C4
ptr28=0116E5C8
ptr29=0116E5CC
..........删除完成...................
ptr0=0116E558
ptr1=0116E55C
ptr2=0116E560
ptr3=0116E564
ptr4=0116E568
ptr5=0116E56C
ptr6=0116E570
ptr7=0116E574
ptr8=0116E578
ptr9=0116E57C
ptr10=0116E580
ptr11=0116E584
ptr12=0116E588
ptr13=0116E58C
ptr14=0116E590
ptr15=0116E594
ptr16=0116E598
ptr17=0116E59C
ptr18=0116E5A0
ptr19=0116E5A4
ptr20=0116E5A8
ptr21=0116E5AC
ptr22=0116E5B0
ptr23=0116E5B4
ptr24=0116E5B8
ptr25=0116E5BC
ptr26=0116E5C0
ptr27=0116E5C4
ptr28=0116E5C8
ptr29=0116E5CC

E:\vc_test\LearMordenC\Release\LearMordenC.exe (进程 7724)已退出,返回代码为: 0。
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...

动态分区分配是一种内存管理技术,将内存分成若干个区域,每个区域的大小不同,根据程序的需要进行分配和回收。该技术可以提高内存利用率,减少内存碎片,并且可以动态调整内存分配,适应不同的应用场景。 本次实验主要是通过模拟动态分区分配的过程,来加深对动态分区分配的理解。 实验环境及工具:C++ 编译器,Visual Studio 2019。 实验步骤: 1. 定义数据结构 首先我们定义一个内存块的结构体,包含该内存块的起始地址、大小、是否被分配等信息: ```c++ struct MemoryBlock { int startAddr; // 起始地址 int size; // 大小 bool isFree; // 是否被分配 }; ``` 2. 模拟内存分配 接下来我们模拟内存的分配过程。首先定义一个动态数组来保存内存块的信息,然后按照一定的规则进行内存分配。这里我们采用了首次适应算法(First Fit)来进行内存分配: ```c++ void allocateMemory(vector<MemoryBlock>& mem, int size) { for (int i = 0; i < mem.size(); i++) { if (mem[i].isFree && mem[i].size >= size) { mem[i].isFree = false; if (mem[i].size > size) { MemoryBlock newBlock = { mem[i].startAddr + size, mem[i].size - size, true }; mem.insert(mem.begin() + i + 1, newBlock); } mem[i].size = size; cout << "分配了 " << size << "KB 内存,起始地址为 " << mem[i].startAddr << "KB" << endl; return; } } cout << "内存不足,无法分配" << endl; } ``` 该函数遍历内存块数组,找到第一个空闲内存块大小大于等于需要分配的内存大小的内存块,并将其分配出去。如果该内存块大小大于分配的大小,则将剩余部分插入到内存块数组中。 3. 模拟内存回收 当程序不再需要某个内存块时,需要将该内存块回收,以便下一次分配。这里我们采用了合并相邻空闲块的方法来进行内存回收。 ```c++ void freeMemory(vector<MemoryBlock>& mem, int startAddr) { for (int i = 0; i < mem.size(); i++) { if (mem[i].startAddr == startAddr) { mem[i].isFree = true; cout << "已释放 " << mem[i].size << "KB 内存,起始地址为 " << mem[i].startAddr << "KB" << endl; if (i > 0 && mem[i - 1].isFree) { mem[i - 1].size += mem[i].size; mem.erase(mem.begin() + i); i--; } if (i < mem.size() - 1 && mem[i + 1].isFree) { mem[i].size += mem[i + 1].size; mem.erase(mem.begin() + i + 1); } return; } } cout << "该内存块不存在,无法释放" << endl; } ``` 该函数遍历内存块数组,找到需要回收的内存块,并将其标记为空闲。然后检查该内存块的前后是否有空闲内存块,如果有,则将它们合并成一个更大的空闲内存块。 4. 模拟内存使用 最后,我们编写一个简单的程序来模拟内存的使用。该程序会不断地进行内存分配和回收,并且每次进行操作后会输出当前内存块数组的信息。 ```c++ int main() { vector<MemoryBlock> mem; mem.push_back({ 0, 1024, true }); // 初始化内存块 while (true) { cout << "1. 分配内存" << endl; cout << "2. 释放内存" << endl; cout << "3. 查看内存情况" << endl; cout << "4. 退出" << endl; cout << "请输入操作编号:"; int choice, size, addr; cin >> choice; switch (choice) { case 1: cout << "请输入需要分配的内存大小(KB):"; cin >> size; allocateMemory(mem, size); break; case 2: cout << "请输入需要释放的内存起始地址(KB):"; cin >> addr; freeMemory(mem, addr); break; case 3: for (int i = 0; i < mem.size(); i++) { cout << "起始地址:" << mem[i].startAddr << "KB,大小:" << mem[i].size << "KB,状态:"; if (mem[i].isFree) { cout << "空闲" << endl; } else { cout << "已分配" << endl; } } break; case 4: return 0; default: cout << "操作编号无效,请重新输入" << endl; } } return 0; } ``` 实验结果: 运行程序后,可以看到以下界面: ``` 1. 分配内存 2. 释放内存 3. 查看内存情况 4. 退出 请输入操作编号: ``` 输入 1 可以进行内存分配,输入 2 可以进行内存回收,输入 3 可以查看当前内存块数组的情况,输入 4 可以退出程序。下面是一些操作示例: ``` 请输入操作编号:1 请输入需要分配的内存大小(KB):256 分配了 256KB 内存,起始地址为 0KB 请输入操作编号:1 请输入需要分配的内存大小(KB):512 分配了 512KB 内存,起始地址为 256KB 请输入操作编号:3 起始地址:0KB,大小:256KB,状态:已分配 起始地址:256KB,大小:512KB,状态:已分配 请输入操作编号:2 请输入需要释放的内存起始地址(KB):0 已释放 256KB 内存,起始地址为 0KB 请输入操作编号:3 起始地址:0KB,大小:768KB,状态:空闲 请输入操作编号:4 ``` 可以看到,程序可以正常进行内存分配和回收,并且在操作后正确地合并了相邻空闲块,保证了内存块的连续性。 总结: 通过本次实验,我们深入了解了动态分区分配的原理,掌握了内存分配和回收的实现方法,提高了对内存管理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值