好友内存分配-主要功能
buddy memory allocation - main function
我是C++新手,我发现了这个好友系统内存分配的代码,但没有主函数,所有成员函数都是正确的,我想让你们帮我完成主函数,我想分配一些内存,然后显示分配前后的内存状态,然后释放内存以验证好友是否正在合并,并显示可用块的列表
--BuddyPool.h-
#ifndef BUDDYPOOL_INC
#define BUDDYPOOL_INC
class BuddyPool{
public:
enum Status { free, reserved };
struct Header
{
Status status: 1;
//unsigned int k : bitsizeof(unsigned int) - 1U;
unsigned int k : 31;
};
struct Block : public Header
{
//enum { size = 16 };
enum { size = 64 };
struct Links
{
Block *next;
Block *prev;
};
union
{
Links link;
char userPart [size - sizeof(Header)];
};
};
private:
unsigned int m;
unsigned int numberOfBlocks;
Block *pool;
Block *sentinel;
static void Unlink(Block &);
static void InsertAfter(Block &, Block &);
Block &Buddy(Block &) const;
public:
BuddyPool(size_t);
~BuddyPool();
void *Acquire(size_t);
void Release(void *);
};
#endif /* ----- #ifndef BUDDYPOOL_INC ----- */
--BuddyPool.cpp--
#include <WinDef.h>
#include "BuddyPool.h"
unsigned int Log2Ceil(unsigned int val){
unsigned int L;
for (L = 0; (1ul<<L) < val; L++);
return L;
}
BuddyPool::BuddyPool(size_t bytes)
: m(Log2Ceil(bytes))
, numberOfBlocks( (1 << m) / sizeof(Block))
, pool (new Block[numberOfBlocks + m +1])
, sentinel(pool + numberOfBlocks)
{
for (unsigned int i = 0; i <= m; ++i) {
sentinel[i].link.next = &sentinel[i];
sentinel[i].link.prev = &sentinel[i];
}
Block &head = pool[0];
head.status = free;
head.k = m;
InsertAfter(sentinel[m], head);
}
BuddyPool::~BuddyPool(){
delete [] pool;
}
void *BuddyPool::Acquire(size_t bytes){
unsigned int kPrime = Log2Ceil(bytes + sizeof(Header));
unsigned int i = kPrime;
while (i <= m && sentinel[i].link.next == &sentinel[i]) {
++i;
}
if (i > m) {
return NULL; // throw bad_alloc("out of memory");
}
Block &block = *sentinel[i].link.next;
Unlink(block);
while (block.k > kPrime) {
block.k -= 1;
Block &buddy = Buddy(block);
buddy.status = free;
buddy.k = block.k;
InsertAfter(sentinel[buddy.k], buddy);
}
block.status = reserved;
return block.userPart;
}
void BuddyPool::Release(void *arg){
Block &block = *reinterpret_cast<Block *>(
reinterpret_cast<Header *>(arg) - 1U);
if (&block < pool || &block >= pool + numberOfBlocks) {
return; // throw invalid_argument("invalid pointer");
}
block.status = free;
Block *ptr;
for (ptr = █ ptr->k < m; ptr->k += 1) {
Block &buddy = Buddy(*ptr);
if (buddy.status == reserved || buddy.k != ptr->k) {
break;
}
Unlink(buddy);
if (&buddy < ptr) {
ptr = &buddy;
}
}
InsertAfter(sentinel[ptr->k], *ptr);
}
BuddyPool::Block &BuddyPool::Buddy(Block &block) const{
unsigned int addr = reinterpret_cast<unsigned int>(&block) + (1 << block.k);
return *(reinterpret_cast<Block *>(addr));
}
void BuddyPool::Unlink(Block &block){
if (block.link.next) {
block.link.next->link.prev = block.link.prev;
}
if (block.link.prev) {
block.link.prev->link.next = block.link.next;
}
block.link.next = block.link.prev = █
}
void BuddyPool::InsertAfter(Block &src, Block &block){
block.link.next = src.link.next;
block.link.prev = &src;
if (src.link.next) {
src.link.next->link.prev = █
}
src.link.next = █
}
您可以从调用公共函数开始。
将内部活动可视化要困难得多。对此没有简单的答案。对于某些语言,如python,有可视化工具,甚至在线可视化工具,但对于c++来说,要求它就像要求SO读者为您开发应用程序。。。l
更高级的用法:将调用封装在标准分配器类中(请参阅std::allocator
),然后您可以使用它来为例如std::vector
执行分配和解除分配。
和/或您可以为某些类定义operator new
和operator delete
(分别为单个对象分配和dellocation函数)
相关文章:
- 带内存和隔离功能的SQLite
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- C++功能泄漏内存,我是C++新手,不确定如何解决
- OPENCL-如何使辅助功能返回阵列并将内存的部分从恒定内存空间转移到私有
- 是否可以在内存中修改功能
- 如何停止功能中的内存泄漏
- 将参数传递给const在内存中的副本的功能
- 有没有办法获得功能大小并分配内存以复制和执行
- 列出当前过程并使用未记录的当前功能编写内存的软件技巧
- 模板功能以操纵内存
- c++ std map 的擦除功能是否释放了指针键的内存?
- 按模板类划分的自动内存池功能
- 代码ARP数组,指针和内存分配(Windows IP功能)的不可理解的部分
- P/调用C 功能后清理内存
- 跟踪每个功能的内存分配
- 功能中的内存泄漏,返回指针
- 调整数组大小功能不会更改内存位置
- 删除在另一个功能中分配的内存
- 通过功能提升共享内存中的C++结构
- "new"也会导致功能内存泄漏吗?