博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言指针加1问题以及字节对齐问题
阅读量:5098 次
发布时间:2019-06-13

本文共 1392 字,大约阅读时间需要 4 分钟。

今天早上自己写了一段代码,然后测试的时候发现结果总是和预期的不一样,而且偏差的有点离谱,冥思苦想了将近五个小时,最后在我要开始怀疑人生的时候,发现原来是自己犯了一个极其低级但又容易被忽略的问题。好吧,我承认我有点丢程序员的人了。

废话不多说,直接开始用例子来说明吧:

我的代码里有两个结构体,假设为结构体Head和结构体Data,其结构如下:

struct Data{     int a;     char b;     short c;     long d;    };struct Head{     int fieldcount;     Data fielddata[1];};

其中,结构体Head包含结构体Data的指针,且fieldcount表示后续有多少Data。我是将这个数据存储在缓冲区中(假设缓冲区为char buf[1024])。当我通过如下代码取数据的时候,发现取出来的数据结构体Data完全不是自己要的:

1         Head* h = (Head*) (buf+offset);2         size_t datalen = sizeof (Head) + (h->fieldcount-1) * sizeof (Data);3         offset += datalen;4 5         for(size_t i=0;i
fieldcount;++i)6 {7 Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));8 printf("a: %d b: %c \n", data->a,data->b);9 }

不知道大家看出来问题没有,我竟然研究这一段这么简单的代码研究了五个小时,简直丢人啊。直接说问题吧。问题出在这句代码:

1 Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));

我的本意是想依次取出来Head后面的data的,即通过Data指针操作内存。可是我却忘记了(指针+偏移量)的含义了。这里的偏移量看起来很正确,是以字节为单位的数,其实对于指针来说,是加了偏移量*sizeof(Head)的字节数,这里的偏移量,意思是加了多少个Head,这也是指针的奇妙之处,也是平时容易忽略的地方。所以每次我读Data的时候,总是读的很靠后面的内存,到时候读的数据存在问题。修改后的代码如下:

1 Data* data=(Data*)((char*)h+sizeof(Head)+(i-1)*sizeof(Data));

当然,我的环境是在linux上,以utf-8为编码格式,所以char是一个字节,当然这里具体环境可以修改代码。

 

 

温馨提示:

在调试代码的时候,还发现一个容易出错的地方,就是注意字节对齐问题。当你把数据存到缓冲区时,如果数据是字节对齐,例如以1字节对齐的时候,如果取得时候没有声明对齐,那会存在意想不到的效果,哈哈聪明的你可以尝试,反正我是尝试过了。

 

转载于:https://www.cnblogs.com/fnlingnzb-learner/p/7667579.html

你可能感兴趣的文章
<转>关于MFC的多线程类 CSemaphore,CMutex,CCriticalSection,CEvent
查看>>
jquery中ajax返回值无法传递到上层函数
查看>>
css3之transform-origin
查看>>
[转]JavaScript快速检测浏览器对CSS3特性的支持
查看>>
Master选举原理
查看>>
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
小别离
查看>>
微信小程序-发起 HTTPS 请求
查看>>
WPF动画设置1(转)
查看>>
backgound-attachment属性学习
查看>>
个人作业——关于K米的产品案例分析
查看>>
基于node/mongo的App Docker化测试环境搭建
查看>>
java web 中base64传输的坑
查看>>
java 中的线程(一)
查看>>
秒杀9种排序算法(JavaScript版)
查看>>
素数判断BFS之“Prime Path”
查看>>
Activiti入门 -- 环境搭建和核心API简介
查看>>
struts.convention.classes.reload配置为true,tomcat启动报错
查看>>
MySQL的并行复制多线程复制MTS(Multi-Threaded Slaves)
查看>>
Django中间件
查看>>