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. java 实现视频转换通用工具类:视频截图-Ffmpeg(四)

    java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) java 实现视频转换通用工具类:视频相互转换-Ffmpeg ...

  2. spring mvc处理json

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. 【22】将成员变量声明为private

    1.为什么要将成员变量声明为private,语法一致性,只通过方法暴露接口. 2.使用方法,可以对成员变量更精确的控制.比如:为所有可能的实现提供弹性,不同实现可以替换:控制可读可写:验证约束条件:处 ...

  4. TQ210裸机编程(2)——LED流水灯

    两个文件start.S和led.c start.S .global _start                @声明一个全局的标号 _start:     bl main               ...

  5. [ES6] ES6 Parameter Object Destructuring with Required Values

    Not only can you provide default values when using ES6 parameter object destructuring, but you can a ...

  6. endif、endforeach

    <?php if ($a == 5): ?>  <div>等于5</div><?php elseif ($a == 6): ?>  <div> ...

  7. Azure PowerShell 创建虚拟机

    # 指定订阅名称$subscriptionName="订阅名称"# 指定云服务名称$serviceName="云服务名称"# 指定用来保存虚拟机VHD的存储$s ...

  8. angualrjs学习总结三(http、select、表格、指令以及事件)

    一:http XMLHttpRequest:$http是angularjs的一个核心服务,用于读取远程服务器的数据.$http.get(url) 是用于读取服务器数据的函数.举例:<div ng ...

  9. SWT中的布局之-----FormLayout(表格式布局)

    表格式(FormLayout类) 表格式布局管理器,通过创建组件各个边的距离来布局组件,和GridLayout一样强大. 用GridLayout与FormLayout都可以实现相同的界面效果,但有时使 ...

  10. uva - 10833 Supermean(二项式系数,对指数)

    模拟发现,每个元素求和时,元素的系数是二项式系数,于是ans=sum(C(n-1,i)*a[i]/2^(n-1)),但是n太大,直接求会溢出,其实double的范围还是挺大的,所以可以将组合数转化成对 ...