如何在指定的地址上创建C++对象
如果已经掌握在静态存储区上创建对象的方法,那么可以扩展一下,可以在任意地址上创建C++对象。
解决方案:
-在类中重载new/delete操作符
-在new的操作符重载函数中返回指定的地址
-在delete操作符重载中标记对应的地址可用
自定义动态对象的存储空间
第二个实验指定了空间为静态存储区中的空间,现在扩展一下不指定具体的空间是哪里,可以临时的动态做决定。
#include <iostream>
#include <string>
#include <cstdlib> 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<char*>(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;
}

如何在指定的地址上创建C++对象的更多相关文章
- 项目心得——按照指定的日期/时间创建Date对象
项目心得——按照指定的日期/时间创建Date对象 有时,在做项目中,需要获得指定日期的Date对象,这个指定的日期或者时间可能不是当前的时间.下面讲解两种获取指定日期/时间的Date对象的方法: pa ...
- 在DB2 for z/os上创建指定pagesize的数据库
ASNTDIFF的diff table有一列类型为varchar 15000,z上创建db默认的pagesize是4K,无法创建table,所以需要创建一个大pagesize的database. db ...
- Kubernetes集群向指定节点上创建容器
如果需要限制Pod到指定的Node上运行,则可以给Node打标签并给Pod配置NodeSelector. 给节点添加标签 首先查看节点信息 [root@k8s-master ~]# kubectl g ...
- 在腾讯云上创建您的SQL Cluster(3)
版权声明:本文由李斯达原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/250 来源:腾云阁 https://www.qclo ...
- 菜鸟玩云计算之十五:在Ubuntu上创建和管理Redhat虚拟机
菜鸟玩云计算之十五:在Ubuntu上创建和管理Redhat虚拟机 chedou@hgdb.net 虚拟机给工作带来巨大的便利,不仅仅体现在资源的按需使用,而且配置的迁移特别方便.本文将使用Ubuntu ...
- 怎样利用Heartbeat与Floating IP在Ubuntu 14.04上创建高可用性设置
提供 ZStack社区 内容简单介绍 Heartbeat是一款开源程序,负责将集群基础设施容量--包括集群成员与消息收发--交付至客户server. Hearbeat在高可用性server基础设施其中 ...
- js在table指定tr行上或底下添加tr行
js在table指定tr行上或下面添加tr行 function onAddTR(trIndex) { var tb = document.getElementB ...
- 在github上创建自己的代码仓库
git用了很久了,github也用很久了,但一直都是使用别人的项目, 最近想把自己写的一些代码放到自己的帐号上去 以为就是很简单的代码推送,真正做一次时候才发现,原来坑还不少呢, 就把这次的经历记录一 ...
- 关于如何在github上创建团队开发环境
今天想写个如何在github上创建团队开发环境的博客.送给那些还不知道如何在github上创建团队开发环境的开发人员. 1.首先,当然你要有个github的账号.具体怎么注册我这里就不说了.可以上gi ...
随机推荐
- CF1025B题解
其他的几篇题解大多都是先求了 \(c_i \gets lcm(a_i,b_i)\) ,然后求全部 \(c_i\) 的最大公约数,但是对每一组数都求一下 \(lcm(a_i,b_i)\) 会增加时间复杂 ...
- 【洛谷P4933 大师】动态规划
题目描述 ljt12138首先建了n个特斯拉电磁塔,这些电塔排成一排,从左到右依次标号为1到n,第i个电塔的高度为h[i]. 建筑大师需要从中选出一些电塔,然后这些电塔就会缩到地下去.这时候,如果留在 ...
- shell脚本(10)-流程控制while
一.while循环介绍 while循环与for一样,一般不知道循环次数使用for,不知道循环的次数时推荐使用while 二.while语法 while [ condition ] #条件为真才会循环, ...
- python3实现名片管理系统(文件版)
def menu(): #首先定义功能列表函数menu() print(" 名片管理系统 V1.0 ") print("1:增加新用户") print(&quo ...
- vue 使用 lang="scss" 报错
npm install sass-loader@7.3.1 --save-dev npm install node-sass --save npm install style-loader --sav ...
- JS 之循环 应用案例1
应用场景:将el-select下拉框的lab值,显示在下面的详情text框,见下图 用到了 el-select 传值,js循环判断options.code是否等于传进来的值,等于就break; tex ...
- 常用PLC与ifix/intouch驱动地址匹配规则
常用PLC与IFIX /的InTouch驱动地址匹配规则如下(持续更新): 1.施耐德M580<----->Intouch的/ IFIX: AI:400102<-----> 4 ...
- GoldenEye-v1靶机
仅供个人娱乐 靶机信息 下载地址:https://pan.baidu.com/s/1dzs_qx-YwYHk-vanbUeIxQ 一.主机扫描 二.信息收集 三.漏洞的查找和利用 boris I ...
- 【LeetCode】169. 多数元素
169. 多数元素 知识点:数组:排序:消消乐:分治: 题目描述 给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的, ...
- 学习vue过程中遇到的问题
1.vue-quill-editor动态禁用 项目中把vue-quill-editor单独封装成了一个组件,通过props传递readOnly参数来设置是否禁用editor.开发中发现可以实现禁用效果 ...