问题:memcpy一段内存到std::bitset里,bitset里的内存数据和被拷贝的内存数据对应不上

代码如下:

#include <iostream>
#include <bitset>
using namespace std;
int main()
{
char a[5] = { 0x00,0x03,0x03,0x04,0x05 };
std::bitset<16> tBitset;
memcpy(&tBitset, a, 2); std::bitset<16> t2Bitset(3);
int n = sizeof(unsigned long);
system("pause");
return 0;
}

此时我的预期是:tBitset={0x0003}

而实际调试结果如下:

tBitset={0x00C0}

最终不断调试得到原因:

memcpy拷贝传入的参数是char*,一个一个字节拷贝,当我们把tBitset的地址传进去拷贝的时候,做了这么几件事情:

1、将a数组的第一第二2个字节的数据拷贝到tBitset里面

2、char数据隐式转换为unsigned long

3、使用构造函数bitset (unsigned long val);对tBitset构造

具体调试截图如下:

可以看到我们只copy了2个字节可是有4个字节的数据,因为char*转为unsinged long(32位机4字节)

  • 大端模式:数字逻辑高位存储在内存的物理低位
  • 小端模式:数字逻辑低位存储在内存的物理低位

我是小端模式,所以这个 unsigned long 的数据为 00 00 03 00,2^8+2^9=768;转化为16进制是0x300;tBitset是0000 0011 0000 0000;和调试结果截图对应

然而为了测试unsigned long 构造出来的bitset是怎么样的,我用std::bitset<16> t2Bitset(3);16进制是0x3;二进制11 看到内存结果截图为

因此右边第一位是数组第0位

之所以刚开始的预期错误,是因为误以为,传入A地址memcpy,就以为A的内存和被拷贝的内存完全一致,A的数组某一位和内存某一位对应,这种想法是错误的,其实A的数组某一位是由A的构造函数决定的,当我把同一块内存的数据分别以unsigned long 和 string类型作参数传进构造函数去,A数组的同一位值可能就不一样,切记

大小端,memcpy和构造函数的更多相关文章

  1. 大小端 Big-Endian 与 Little-Endian

    应该说没做底层开发(硬件或驱动)的人很可能不会彻底理解大小端的概念,大小端不是简单的一句“大端在前”还是“小端在前”能够概括的问题.在cpu, 内存, 操作系统, 编译选项, 文件,网络传输中均有大小 ...

  2. ARM CPU大小端

    ARM CPU大小端: 大端模式:低位字节存在高地址上,高位字节存在低地址上 小端模式:高位字节存在高地址上,低位字节存在低地址上 STM32属于小端模式,简单的说,比如u32 temp=0X1234 ...

  3. C语言共用体、大小端、枚举

    1.共用体和结构体的相同和不同 (1)相同点就是操作语法几乎相同.(2)不同点是本质上的不同.struct是多个独立元素(内存空间)打包在一起:union是一个元素(内存空间)的多种不同解析方式. # ...

  4. 联合体union和大小端(big-endian、little-endian)

    1.联合体union的基本特性——和struct的同与不同 union,中文名“联合体.共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以 ...

  5. CPU的大小端模式

    不同体系结构的CPU,数据在内存中存放的排列顺序是不一样的. 存储器中对数据的存储是以字节(Byte)为基本单位的,因此,字(Word)和半字(Half-Word)在存储器中就有两种次序,分别称为:大 ...

  6. C++/java之间的Socket通信大小端注意事项

    在一个物联往项目中,需要java云平台与一个客户端做socket定制协议的通信:然而在第一次测试时,并没有按照预想的那样完成解析.查找资料以后是因为客户端的数据读取方式为小端模式,而java默认采用大 ...

  7. 从inet_pton()看大小端字节序

    #include<stdio.h> #include<netinet/in.h> #include<stdlib.h> #include<string.h&g ...

  8. 【转】 CPU大小端

    大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中:小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中. 为什么会有大小端模式之分呢?这是因为 ...

  9. linux kernel 如何处理大小端

    暂时在用MPC8309,不太清楚大小端内核是什么时候给转的. 今天看了关于readl和writel具体实现的文章 今天就主要来分析下readl/writel如何实现高效的数据swap和寄存器读写.我们 ...

随机推荐

  1. 一次修改mysql字段类型引发的技术探究

    说来,mysql数据库是我们项目中用的比较多的库,ORM工具喜欢采用细粒度的MyBatis.这里面就这么引出了两者之间的故事! 首先,说改字段吧,将一个表中的varchar字段改为enum字段.如下: ...

  2. maven添加自定义jar

    mvn install:install-file -Dfile=自定义jar文件路径 -DgroupId=所属组 -DartifactId=项目名 -Dversion=版本 -Dpackaging=j ...

  3. ML平台_饿了么实践

    (转载至:https://zhuanlan.zhihu.com/p/28592540) 说到机器学习.大数据,大家听到的是 Hadoop 和 Spark 居多,它们跟 TensorFlow 是一个什么 ...

  4. excel技巧--批量生成工资条

    要想生成如上图的工资条,快速的方法如下: 1.在工资表右侧建立一升序数字列,完成后再复制该列,重复粘贴一次在该列底部.2.对该表排序:“开始”-->“排序和筛选”-->自定义排序.在对话框 ...

  5. Delphi跨进程访问DBGRID

    要想跨进程访问DBGRID,貌似只能用HOOK,写一个DLL想办法注入到目标进程.注入成功后,使DLL与目标进程在同一进程空间中(其内有一些细节问题,请参见代码),这时可以访问目标进程的VCL组件.并 ...

  6. JS获取坐标

    1.js获取对象的绝对坐标 方法1: function getAbsPoint(e) { var x = e.offsetLeft, y = e.offsetTop; while(e=e.offset ...

  7. 启动bind失败

    systemctl start named 报错: control process exited, code=exited status=1 Failed to start Berkeley Inte ...

  8. STL基础--String

    String 构造 string s1("Hello"); string s2("Hello", 3); //s2: Hel string s3(s1, 2); ...

  9. SVM清晰讲解——线性可分问题

    转载作者:liangdas 引言: 1995年Cortes和Vapnik于首先提出了支持向量机(Support Vector Machine),由于其能够适应小样本的分类,分类速度快等特点,性能不差于 ...

  10. Ubuntu 14.10 下安装Spark

    Spark 是一种与 Hadoop 相似的开源集群计算环境,不过最近非常火.下面介绍安装步骤. 1 安装scala 1.1 我选用的是2.11.4,下载地址http://www.scala-lang. ...