c 和 c++ 最大的特点就是对内存的自由操作,数据类型,其实都是对内存的一种解释方式。C语言中常用的一个技巧就是尾随数据,网络编程中经常会用到这个特性,

特别是以前写完成端口的时候,这个特性肯定是会用到,跟IOCP的API特性相关。c++中也有类似的new也可以使用。

e1:尾随内存与指针解释

// c++ std
#include <iostream> // c std
#include <cstdlib>
#include <cstring> struct TestData {
int data_size_;
char data_[];
}; void foo1() {
std::cout << "sizeof(TestData) = " << sizeof(TestData)<<std::endl;
int len = sizeof(TestData) + *sizeof(int);
char *buffer = "hello world";
TestData * data_ptr = reinterpret_cast<TestData*>(new char[len]);
if (nullptr != data_ptr) {
data_ptr->data_size_ = ;
memcpy(data_ptr->data_, buffer, strlen(buffer) + );
std::cout << data_ptr->data_ << std::endl;
std::cout << reinterpret_cast<char *>(data_ptr+) << std::endl;
std::cout << "sizeof(TestData) = " << sizeof(TestData)<<std::endl;
} }
int main(int argc, char* argv[]){
foo1();
getchar();
return ;
}

输出结果:

sizeof(TestData) = 4

hello world

hello world

说面:动态分配的内存比TestData本身的数据大小4要大,而TestData的成员data_是不计内存的,只是其地址依然是在data_size_的内存地址之后。给data_的赋值其实利用的是其后的数据内存,而不是TestData本身的内存,不过,实际使用时最好还是将data_声明为char data_[1]。

e2:C++中的定位new

通常我们用new来动态分配一个对象或者一个对象数组,上面的代码中分配内存时,分配了相对足够大的内存,然后在其上面构建字符串。new操作符其实也可以在已有内存上构建对象,继续在刚才的代码上改进一下。

void foo2() {
char * buffer = new char [];
// 利用new在已有内存上构建对象
TestData *data1 = new (buffer) TestData;
if (nullptr == data1) {
return;
}
// 再次利用new在data1后构建第二个TestData对象
// 此时new是没有分配内存的
TestData *data2 = new (data1 + ) TestData;
if (nullptr == data2){
return;
}
data1->data_size_ = ;
memcpy(data1->data_, &data1->data_size_, sizeof(data1->data_size_));
// 这个时候, 由于data2的内存仅随data1之后,data2->data_size_的值为4
std::cout << "data1:" << data1 << std::endl;
std::cout << "data2:" << data2 << std::endl;
std::cout << "data2->data_size_:" << data2->data_size_ << std::endl;
} int main(int argc, char* argv[]){
foo2();
getchar();
return ;
}

输出结果:

data1:001EFBE0

data2:001EFBE4

data2->data_size_:4

c++中动态尾随内存的技巧和定位new的更多相关文章

  1. C语言和C++中动态申请内存

      在C语言和C++的动态内存的使用方法是不同的,在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h>  ...

  2. JVM中对象的内存布局与访问定位

      一.对象的内存布局 已主流的HotSpot虚拟机来说,   在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填 ...

  3. rt-thread中动态内存分配之小内存管理模块方法的一点理解

    @2019-01-18 [小记] rt-thread中动态内存分配之小内存管理模块方法的一点理解 > 内存初始化后的布局示意 lfree指向内存空闲区首地址 /** * @ingroup Sys ...

  4. C语言中动态内存分配的本质是什么?

    摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...

  5. 12个Unity5中优化VR 应用的技巧

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50176429 作者:car ...

  6. java中JVM虚拟机内存模型详细说明

    java中JVM虚拟机内存模型详细说明 2012-12-12 18:36:03|  分类: JAVA |  标签:java  jvm  堆内存  虚拟机  |举报|字号 订阅     JVM的内部结构 ...

  7. Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

    Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf  动态库的后缀为*.so  静态库的后缀为 libxxx.a   ldconfig   目录名 转载自:http://b ...

  8. iOS开发UI篇—IOS开发中Xcode的一些使用技巧

    iOS开发UI篇—IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文 ...

  9. JAVA中堆栈和内存分配原理

    1.栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量 ...

随机推荐

  1. SCOM随笔

    1.在监控群集资源时,安装完agent后,在代理管理-agent属性中选中“允许此代理充当代理并发现其他计算机上的托管对象” 如果监控DC的话,也要选中该选项

  2. hdu 5461 Largest Point 暴力

    Largest Point Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  3. 增强的for循环(或foreach)

    增强的for循环(也称为foreach循环):不用下标变量,顺序的訪问整个数组.不能以其它顺序訪问数组,或者改变数组的元素. for(elementType element: arrayRefVar) ...

  4. SQL Server 2008中的hierarchyid

    这也是SQL Server 2008的一个重要新增特性.主要解决的问题是拥有层次关系的表格.例如我们日常生活中用到最多的组织结构图.我们一般会用一个Region表保存区域数据,而每个区域则又可能会有相 ...

  5. C 二叉树

    二叉树表示法 P127页 /* typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTre ...

  6. Java,javascript,html,css的关系

    内容:,就是制作者放在页面想让访问者浏览的内容 . 主要由java语言提供数据检索.更新.业务处理等. 结构:使内容更加具有逻辑性和易用性,类似于1,2级标题,正文.列表等等. HTML 表现:用于修 ...

  7. 优化sql,返回行数少情况下,NL比hash快好多

    sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt ...

  8. JAVA_Gson

    package com.qf.mobiletrain01; import java.util.List; import com.google.gson.Gson; import com.google. ...

  9. 圆满完成Web安全测试培训课程广州公开班!

    圆满完成Web安全测试培训课程广州公开班! http://gdtesting.com/news.php?id=187 下期<Web安全测试最佳实践>公开课通知:8月9.10日地点:广州 课 ...

  10. 关于@see注解

    所有三种类型的注释文档都可包含@see标记,它允许我们引用其他类里的文档.对于这个标记,javadoc会生成相应的HTML,将其直接链接到其他文档.格式如下: @see 类名@see 完整类名@see ...