如何在指定的地址上创建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 ...
随机推荐
- DNS Bind日志详述
简介 在默认情况下,BIND9 把日志消息写到 /var/log/messages 文件中,而这些日志消息是非常少的,主要就是启动,关闭的日志记录和一些严重错误的消息:而将调试日志信息写入 BIND ...
- 跨域jsonp+jQuery+json+html动态生成表格
1.什么是跨域 浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了. 凡是拥有scr这个属性 ...
- 第七篇 -- photoshop cs6 激活
下载photoshop cs6破解版 下载amtlib.dll 破解就是将amtlib.dll替换,路径:C:\Program Files\Adobe\Adobe Photoshop CS6 (64 ...
- intouch 趋势图Y轴自适应功能完善
在项目中有利用到历史趋势,其y轴往往展示的是该点的最小/最大值范围,对于曲线波动展示不够友好.故而利用自带方法进行完善,以此记录. Histrend1.MinRange=HTGetAutoScaleV ...
- 让自己写的电子笔记连文带图全平台兼容(MarkDown图片显示兼容)
目录 一.工具使用 语言使用:MarkDown 简介 使用原因 使用方法 软件使用:Typora 简介 环境设置搭建 1)搭建图床 2)配置PicGo 3)配置typora 4)测试 图片上传测试 平 ...
- Android技术分享| 实现视频连麦直播
视频连麦产品端核心步骤分析 游客申请连麦/取消申请 主播同意/拒绝申请 音视频发布取消 支持很多观众观看 支持多人连麦 低延时 IM 弹幕 视频连麦技术端调研 emmm,大致可以分为视频采集.编码,传 ...
- 还在用Postman?来,花2分钟体验下ApiPost的魅力
2分钟玩转APIPOST 本文通过简单介绍如何利用ApiPost调试接口和快速的生成接口文档,让您初步体验ApiPost的魅力! 1. API写完想要测试?试试模拟发送一次请求 新建接口,我想模拟发送 ...
- 小白学习Vue第五天(v-model实用的地方)
用法一radio单选项 <!-- 添加name男女选项互斥 --> <label for="male"> <input type="radi ...
- 【LeetCode】316. 去除重复字母
316. 去除重复字母 知识点:栈:单调 题目描述 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次.需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置). 示例 输 ...
- spring学习05(代理模式)
8.代理模式 为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 8.1 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象类来实现 真实角色 : 被 ...