c++中动态尾随内存的技巧和定位new
2024-10-20 18:52:56
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
最新文章
- opengl es中不同的绘制方式
- easyui的datagrid实例实现
- jquery ajax跨域的完美解决方法(jsonp方式)
- NSURLConnection 网络超时的那些事(转别人整理的)
- 由tomcat启动想到的
- springcloud(八):配置中心服务化和高可用
- Cinnamon桌面是怎么回事儿
- 基于Lua脚本解决实时数据处理流程中的关键问题
- oracle03
- PHP正则表达式二分法实现mysql盲注脚本
- 网络基础 外网IP,内网IP,虚拟机的网络设置
- 20165223 结对编程之四则运算week1-阶段性总结
- Ajax和Json实现自动补全
- html干货部分
- Number of Islands I &; II
- 任务失败,因为未找到“AxImpexe”,或未安装正确的 Microsoft Windows SDK
- SQLServer2008 全文检索摘记
- Ubuntu18.04 修改DNS
- NodeJS 难点(网络,文件)的 核心 stream 四: writable
- 【POJ】1835:宇航员【模拟】【三维行走】
热门文章
- JS保留两位小数 四舍五入函数
- Codeforces Round #324 (Div. 2) E. Anton and Ira 贪心
- C# 网络编程之豆瓣OAuth2.0认证具体解释和遇到的各种问题及解决
- Java对数组的操作(二)——集合与数组的切换
- perl指针引用
- linux高级命令组合
- MySQL(16):Select-union(联合查询)
- swift和oc区别----属性部分(参考官方swift2.1文档)
- RESTful HTTP实践
- 详细讲解Android对自己的应用代码进行混淆加密防止反编译