如何在指定的地址上创建C++对象
阅读原文时间:2023年07月08日阅读:3

如果已经掌握在静态存储区上创建对象的方法,那么可以扩展一下,可以在任意地址上创建C++对象。

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

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

第二个实验指定了空间为静态存储区中的空间,现在扩展一下不指定具体的空间是哪里,可以临时的动态做决定。

#include
#include
#include

using namespace std;

class Test
{
private:
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(calloc(c_count, sizeof(char))))); //动态的创建一个标记数组

      if(ret) //当ret为true时,就可以确认这个空间设置是合法的,确实可以在指定的空间上创建对象了。  
    {  
        c\_buffer = memory;  
    }  
    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循环查找在c\_buffer这片空间中哪些是空闲的,可以用于创建一个Test对象。  
        //遍历c\_count个位置,看每个位置有没有对象存在,如果没有对象存在,那么就可以返回这片内存空间。并且在这片内存空间中调用构造函数创建对象。  
          for(int i=0; i<c\_count; i++)  
        {  
            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);  
            int flag = (mem-c\_buffer) % sizeof(Test);

            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()
{
cout << "====== Test Single Object ======" << endl;
Test* pt = new Test;
delete pt;

cout << "====== Test Object Array ======" << endl;
Test* pa[5] = {0};

for(int i=0; i<5; i++)
{
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;  

}

为什么会出现上面的结果,因为我们在main函数中没有指定空间,因此new的时候,它走的是malloc,delete的时候,它走的是free.

修改main函数如下:

int main()
{
char buffer[12] = {0};
Test::SetMemorySource(buffer,sizeof(buffer));

cout << "====== Test Single Object ======" << endl;
Test* pt = new Test;
delete pt;

cout << "====== Test Object Array ======" << endl;
Test* pa[5] = {0};

for(int i=0; i<5; i++)
{
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;  

}