如果已经掌握在静态存储区上创建对象的方法,那么可以扩展一下,可以在任意地址上创建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++对象的更多相关文章

  1. 项目心得——按照指定的日期/时间创建Date对象

    项目心得——按照指定的日期/时间创建Date对象 有时,在做项目中,需要获得指定日期的Date对象,这个指定的日期或者时间可能不是当前的时间.下面讲解两种获取指定日期/时间的Date对象的方法: pa ...

  2. 在DB2 for z/os上创建指定pagesize的数据库

    ASNTDIFF的diff table有一列类型为varchar 15000,z上创建db默认的pagesize是4K,无法创建table,所以需要创建一个大pagesize的database. db ...

  3. Kubernetes集群向指定节点上创建容器

    如果需要限制Pod到指定的Node上运行,则可以给Node打标签并给Pod配置NodeSelector. 给节点添加标签 首先查看节点信息 [root@k8s-master ~]# kubectl g ...

  4. 在腾讯云上创建您的SQL Cluster(3)

    版权声明:本文由李斯达原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/250 来源:腾云阁 https://www.qclo ...

  5. 菜鸟玩云计算之十五:在Ubuntu上创建和管理Redhat虚拟机

    菜鸟玩云计算之十五:在Ubuntu上创建和管理Redhat虚拟机 chedou@hgdb.net 虚拟机给工作带来巨大的便利,不仅仅体现在资源的按需使用,而且配置的迁移特别方便.本文将使用Ubuntu ...

  6. 怎样利用Heartbeat与Floating IP在Ubuntu 14.04上创建高可用性设置

    提供 ZStack社区 内容简单介绍 Heartbeat是一款开源程序,负责将集群基础设施容量--包括集群成员与消息收发--交付至客户server. Hearbeat在高可用性server基础设施其中 ...

  7. js在table指定tr行上或底下添加tr行

    js在table指定tr行上或下面添加tr行 function onAddTR(trIndex)         {             var tb = document.getElementB ...

  8. 在github上创建自己的代码仓库

    git用了很久了,github也用很久了,但一直都是使用别人的项目, 最近想把自己写的一些代码放到自己的帐号上去 以为就是很简单的代码推送,真正做一次时候才发现,原来坑还不少呢, 就把这次的经历记录一 ...

  9. 关于如何在github上创建团队开发环境

    今天想写个如何在github上创建团队开发环境的博客.送给那些还不知道如何在github上创建团队开发环境的开发人员. 1.首先,当然你要有个github的账号.具体怎么注册我这里就不说了.可以上gi ...

随机推荐

  1. Function.identity()

    Java 8允许在接口中加入具体方法.接口中的具体方法有两种,default方法和static方法,identity()就是Function接口的一个静态方法.Function.identity()返 ...

  2. final修饰符(6)-final类

    final修饰的类不可以有子类,例如:java.lang.Math类就是一个final类,它不可以有子类 子类继承父类,可以访问父类的内部数据,可以重写父类的方法来改变父类方法的实现细节,可能导致不安 ...

  3. Leetcode No.14 Longest Common Prefix最长公共前缀(c++实现)

    1. 题目 1.1 英文题目 Write a function to find the longest common prefix string amongst an array of strings ...

  4. cisco 交换机 IOS命令

    1 显示交换机的MAC地址表 user mode : show mac-address-table

  5. gnome环境设置

    1.gnome的环境安装sudo apt-get install gnome2.选择gdm3 开机显示不正常:could not apply the stored configuration for ...

  6. 新iPhone有望加入指纹解锁,你会买吗?

    苹果新款iPhone即将在9月份正式发布,或命名为iPhone 13或者iPhone 12s.据外媒报道,新一代iPhone的屏幕和相机都将迎来重大升级,同时还将首次加入屏下指纹解锁技术.你期待吗? ...

  7. debug:am trace-ipc源码分析

    debug:am trace-ipc源码分析 目录 debug:am trace-ipc源码分析 一.使用 官网介绍 命令提示 小结 二.源码分析 ActivityManagerShellComman ...

  8. java 8新特性 并行流

    使用并行流,提高cpu利用率,提高运算速度 /** * java 8并行流 * 底层运用fork join框架 */ @Test public void test(){ Instant start = ...

  9. odoo12里定时任务

    以odoo12为例: 1. 定义定时任务属性 <record id="ir_cron_submit_auto_action" model="ir.cron" ...

  10. 第一篇 -- Go环境的搭建以及Hello World程序编写

    VS Code的下载和安装 1. 下载链接(本人下载版本VSCodeUserSetup-x64-1.57.0.exe) https://code.visualstudio.com/download 友 ...