C++ 第69-03篇 技巧:自定义内存管理

上午: 哈哈哈哈哈哈哈哈哈哈哈
中午: 哈哈哈哈哈哈哈哈哈哈哈
下午: 哈哈哈哈哈哈哈哈哈哈哈
傍晚: 哈哈哈哈哈哈哈哈哈哈哈
深夜:人间不值得

面试题

如何在指定地址上创建C++对象?

解决方案

在类中重载 new / delete 操作符
在 new 的操作符重载函数中返回指定地址
在 delete 操作符重载中标记对应地址可用

编程实验

自定义动态对象的存储空间


#include <iostream>
#include <string>
#include <cstdlib>    //   calloc

using namespace std;

class Test
{
 	static unsigned int c_count;
	static char *c_buffer;   // 定义一个静态的字节数组(静态存储区)
	static char *c_map;
	
	int m_value;

public:
	/* 空间设置函数 */
	static bool SetMemorySource(char* memory, unsigned int size)  // 动态指定 我们想在什么内存空间创建对象
    {
        bool ret = false;
        
        c_count = size / sizeof(Test);  // 传进来的空间   最多可创建的对象个数
        
        ret = (c_count && (c_map = reinterpret_cast<char*>(calloc(c_count, sizeof(char)))));  // 动态创建标记数组
        
        if( ret )
        {
            c_buffer = memory;  // 将空间设置到 c_buffer 指针上去
        }
        else
        {
            free(c_map);
            
            c_map = NULL;
            c_buffer = NULL;
            c_count = 0;
        }
        
        return ret;  // 返回值的意义: 可以告诉函数调用者,当前的动态空间设置是否成功
    }
    
    
	void* operator new (unsigned int size)  
	{
		void* ret = NULL;
		
		if( c_count > 0 )   // 如果说,有指定的具体空间
		{
			for(int i=0; i<c_count; i++)  // 通过循环查找buffer中空闲位置,用于创建 Test 对象
		    {
		        if( !c_map[i] )         // 如果没被标记(没有对象存在)
		        {
		            c_map[i] = 1;
		            
		            ret = c_buffer + i * sizeof(Test); //查找 c_buffer 可用空间的首地址
		            
		            cout << "succeed to allocate memory: " << ret << endl;
		            
		            break;
		        }
        	}
        }
        else
        {
        	ret = malloc(size);
        }
	
		return ret; 
	}


	void operator delete (void* p)  
	{
		if( p != NULL )
        {
        	if( c_count > 0 )
        	{
		        char* mem = reinterpret_cast<char*>(p);
		        int index = (mem - c_buffer) / sizeof(Test);  // 指针的减法运算,得到:要释放的动态对象在c_map[]标记数组中的位置
		        int flag = (mem - c_buffer) % sizeof(Test);   // 这些位置必须是固定的,如果flag不为0,那么指针不合法;
		        
		        if( (flag == 0) && (0 <= index) && (index < c_count) ) // 合法
		        {
		            c_map[index] = 0;  
		            
		            cout << "succeed to free memory: " << p << endl;
		        }
            }
            else
            {
            	free (p);
            }
        }

	}
};

unsigned int Test::c_count = 0;
char* Test::c_buffer = NULL;                 // 静态数组在类外分配空间, 定义静态内存空间
char* Test::c_map = NULL;                    // 标记数组,用来标记在哪里已经创建了对象


int main(int argc, char *argv[])
{

	char buffer[12] = {0};  // 在栈定义空间  12字节-> 3个对象
	Test::SetMemorySource(buffer, sizeof(buffer));  // 将空间设置进去

	// 验证1
 	cout << "===== Test Single Object =====" << endl;
	Test* pt = new Test;
	delete pt;
	cout << "===== Test Object Array =====" << endl;
	
	
	// 验证2
	Test* pa[5] = {0};
	
    for(int i=0; i<5; i++)  // 动态创建5个对象  最后一个为0
    {
        pa[i] = new Test;
        
        cout << "pa[" << i << "] = " << pa[i] << endl;
    }
    
    for(int i=0; i<5; i++)
    {
        cout << "delete " << pa[i] << endl;
        
        delete pa[i];
    }

	return 0;
}

// 如果不自己定义空间,这时虽然重载了 new /delete , 但是所返回的还是堆空间
// 通过重载,我们可以在任意指定位置创建C++对象

感谢关注,文章持续高速更新中······

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页