如果已经掌握在静态存储区上创建对象的方法,那么可以扩展一下,可以在任意地址上创建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. java集合(1)-概述

    Java集合类是一种特别有用的工具类,可用于存储数量不等的对象,并可以实现常用的数据结构,如栈,队列等,此外Java集合还可以用于保存具有映射关系的关联数组.java集合大致可分为Set,List,Q ...

  2. Git初始化本地已有项目

    1.初始化仓库 git init 2.remote git remote add origin 仓库地址 3.从远程分支拉取master分支并与本地master分支合并 git pull origin ...

  3. PAT甲级:1152 Google Recruitment (20分)

    PAT甲级:1152 Google Recruitment (20分) 题干 In July 2004, Google posted on a giant billboard along Highwa ...

  4. IO流之节点流(字符流)和数据流关闭

    ​输入流----Reader 1 public class Reader { 2 public static void main(String[] args) throws Exception { 3 ...

  5. 用Pygal画一个英雄能力的图

    效果图: 这是在google浏览器下打开的html. play.py #!/usr/bin/env python # _*_ coding: UTF-8 _*_ """= ...

  6. Python基础之subprocess

    前言 subprocess这个函数很好用,类似于控制台执行,功能很多,今天先介绍subprocess调用exe,并行调用两个或两个以上的exe. Subprocess调用exe 调用exe有几种方式, ...

  7. 【用例】编写App测试用例的关注点

    编写App测试用例的关注点 如何做到测试用例的百分百覆盖一直是测试用例编写过程中的难点,首先在测试时我们经常会遇见一些常见的bug,那么我们可以在编写测试用例时考虑到这些点.    一:关于业务逻辑 ...

  8. Skywalking-04:扩展Metric监控信息

    扩展 Metric 监控信息 官方文档 Source and Scope extension for new metrics 案例:JVM Thread 增加 Metrics 修改 Thread 的定 ...

  9. java基于mongodb实现分布式锁

    原理 通过线程安全findAndModify 实现锁 实现 定义锁存储对象: /** * mongodb 分布式锁 */ @Data @NoArgsConstructor @AllArgsConstr ...

  10. Jupyter Kernel Error 解决办法

    首先在pycharm的terminal中输入 python -m ipykernel install --user 之后会如下图显示: 这就是kernel的安装路径. 然后输入: jupyter ke ...