C语言指针加1问题以及字节对齐问题
今天早上自己写了一段代码,然后测试的时候发现结果总是和预期的不一样,而且偏差的有点离谱,冥思苦想了将近五个小时,最后在我要开始怀疑人生的时候,发现原来是自己犯了一个极其低级但又容易被忽略的问题。好吧,我承认我有点丢程序员的人了。
废话不多说,直接开始用例子来说明吧:
我的代码里有两个结构体,假设为结构体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完全不是自己要的:
Head* h = (Head*) (buf+offset);
size_t datalen = sizeof (Head) + (h->fieldcount-) * sizeof (Data);
offset += datalen; for(size_t i=;i<h->fieldcount;++i)
{
Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));
printf("a: %d b: %c \n", data->a,data->b);
}
不知道大家看出来问题没有,我竟然研究这一段这么简单的代码研究了五个小时,简直丢人啊。直接说问题吧。问题出在这句代码:
Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));
我的本意是想依次取出来Head后面的data的,即通过Data指针操作内存。可是我却忘记了(指针+偏移量)的含义了。这里的偏移量看起来很正确,是以字节为单位的数,其实对于指针来说,是加了偏移量*sizeof(Head)的字节数,这里的偏移量,意思是加了多少个Head,这也是指针的奇妙之处,也是平时容易忽略的地方。所以每次我读Data的时候,总是读的很靠后面的内存,到时候读的数据存在问题。修改后的代码如下:
Data* data=(Data*)((char*)h+sizeof(Head)+(i-)*sizeof(Data));
当然,我的环境是在linux上,以utf-8为编码格式,所以char是一个字节,当然这里具体环境可以修改代码。
温馨提示:
在调试代码的时候,还发现一个容易出错的地方,就是注意字节对齐问题。当你把数据存到缓冲区时,如果数据是字节对齐,例如以1字节对齐的时候,如果取得时候没有声明对齐,那会存在意想不到的效果,哈哈聪明的你可以尝试,反正我是尝试过了。
C语言指针加1问题以及字节对齐问题的更多相关文章
- c语言指针占几个字节
指针即为地址,指针几个字节跟语言无关,而是跟系统的寻址能力有关,譬如以前是16为地址,指针即为2个字节,现在一般是32位系统,所以是4个字节,以后64位,则就为8个字节. 可以在自己的电脑上测试下: ...
- C语言数组和指针的理解_在取地址运算上的操作_指针加减操作_a 和&a 的区别
1.一个实例+理论分析 在了解数组和指针的访问方式前提下,下面再看这个例子: main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); pr ...
- C语言中的指针加减偏移量
C语言指针偏移技巧(也是一个要注意的坑) - 陈杰柱的博客 - CSDN博客 https://blog.csdn.net/cjzjolly/article/details/82116772 C语言中 ...
- C语言 指针小结
指针 -->指针变量 类型名 *变量名 int *point1; char *point2; 注意:*p可以直接使用,它代表指针p指向的变量,*p可以当做被指向的变量使用!~~~~ 一个变量的地 ...
- iOS学习07之C语言指针
本次随笔主要是为了学习和理解C语言中的指针,指针树状图如下: 1.访问数据的两种方式 1> 直接访问:定义变量后,直接访问变量 ; printf("a = %d\n", a) ...
- 不可或缺 Windows Native (7) - C 语言: 指针
[源码下载] 不可或缺 Windows Native (7) - C 语言: 指针 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 指针 示例cPointer.h #i ...
- C语言指针学习
C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...
- 【C】用我所学去讲C语言指针
很多人不敢讲C的指针,有些人讲不清,有些人怕讲错.初生牛犊不怕虎,就让我讲讲. 下面开始. 一.指针的定义 指针是内存单元的编号.内存单元是以字节为单位的.所以指针就是字节的编号. 比如我们的个人电 ...
- 彻底搞定C语言指针(精华版)
1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ 6 7 8 9 10 11 12 ...
随机推荐
- LoadRunner可以把关联取值当作检查点来使用
在性能测试过程中,很多人都会想通过使用检查点来检查系统响应是否正常,LR的51Testing软件测试网E$S ]:x(d a6h.G \(y 检查点对“死”的,静态的 可以做到检查作业,但是对于动态时 ...
- C#后台获取ajax传来的xml格式数据值
前台: var xml = "<root>"; if(Name!=null) { xml += "<name>"+Name +" ...
- es6导入导出模块
在JavaScript ES6中,export与export default均可用于导出常量.函数.文件.模块等,你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方 ...
- Android Service AIDL
http://blog.csdn.net/liuhe688/article/details/6400385 在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成. AID ...
- Array.reduce()方法的使用
起因是学习异步函数的串行与并行写法时,发现reduce方法可以简化写法,然后看到一篇博客里面这样一段代码: var array = [1, [2, [3, 4], 5], 6]; function f ...
- 第9天-BOM和DOM
什么是DOM 文档对象模型(Document Object Model),DOM作用:可以去修改网页内容.样式.结构. 每个浏览器都会把html文档解析成dom树,就可以用相关方法和属性操作网页元素 ...
- ESXI 5.5卡在LSI_MR3.V00
方法一 故障现象 此问题无论使用VMware官方镜像还是HP的自定义镜像都会出现一下情况并卡着不动.(此文档普遍存在各种服务器上,包括其它厂商服务器) 故障原因: 故障原因VMware官方和HP官方并 ...
- 数据仓库之父——Bill Inmon(转载)
从此处转载 http://blog.sina.com.cn/s/blog_615f9dba0100f67p.html 比尔·恩门(Bill Inmon),被称为数据仓库之父,最早的数据仓库概念提出者, ...
- bzoj 3437: 小P的牧场 -- 斜率优化
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MB Description 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号), ...
- ArrayList源码阅读----JDK1.8
//定义一个默认的长度10 private static final int DEFAULT_CAPACITY = 10; //定义空的数组 private static final Object[] ...