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

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

我的代码里有两个结构体,假设为结构体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问题以及字节对齐问题的更多相关文章

  1. c语言指针占几个字节

    指针即为地址,指针几个字节跟语言无关,而是跟系统的寻址能力有关,譬如以前是16为地址,指针即为2个字节,现在一般是32位系统,所以是4个字节,以后64位,则就为8个字节. 可以在自己的电脑上测试下: ...

  2. C语言数组和指针的理解_在取地址运算上的操作_指针加减操作_a 和&a 的区别

    1.一个实例+理论分析 在了解数组和指针的访问方式前提下,下面再看这个例子: main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); pr ...

  3. C语言中的指针加减偏移量

    C语言指针偏移技巧(也是一个要注意的坑) - 陈杰柱的博客 - CSDN博客  https://blog.csdn.net/cjzjolly/article/details/82116772 C语言中 ...

  4. C语言 指针小结

    指针 -->指针变量 类型名 *变量名 int *point1; char *point2; 注意:*p可以直接使用,它代表指针p指向的变量,*p可以当做被指向的变量使用!~~~~ 一个变量的地 ...

  5. iOS学习07之C语言指针

    本次随笔主要是为了学习和理解C语言中的指针,指针树状图如下: 1.访问数据的两种方式 1> 直接访问:定义变量后,直接访问变量 ; printf("a = %d\n", a) ...

  6. 不可或缺 Windows Native (7) - C 语言: 指针

    [源码下载] 不可或缺 Windows Native (7) - C 语言: 指针 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 指针 示例cPointer.h #i ...

  7. C语言指针学习

    C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...

  8. 【C】用我所学去讲C语言指针

    很多人不敢讲C的指针,有些人讲不清,有些人怕讲错.初生牛犊不怕虎,就让我讲讲. 下面开始. 一.指针的定义  指针是内存单元的编号.内存单元是以字节为单位的.所以指针就是字节的编号. 比如我们的个人电 ...

  9. 彻底搞定C语言指针(精华版)

    1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ 6 7 8 9 10 11 12 ...

随机推荐

  1. ServiceWorker pwa缓存

    index.js if ( navigator.serviceWorker ) { console.log("cache index") window.addEventListen ...

  2. Jquery 实现轮播图

    jq 轮播图 function banner_show(){ var left_btn = $("#banner_tag_left"); //获取左侧单击按钮 var right_ ...

  3. 隐马尔可夫模型(Hidden Markov Model)

    隐马尔可夫模型(Hidden Markov Model) 隐马尔可夫模型(Hidden Markov Model, HMM)是一个重要的机器学习模型.直观地说,它可以解决一类这样的问题:有某样事物存在 ...

  4. PHP库函数积累,持续更新

    1. gethostbyname($server_name) 作用:根据给定的域名获取对应的ip 示例:echo gethostbyname("www.baidu.com"); 2 ...

  5. 切换java版本

    First, clean your project: Project > Clean If that doesn't fix things... Second check your projec ...

  6. Tornado(二)

    跨站请求伪造CSRF 开启xsrf(就是叫法不一样和csrf一样),'xsrf_cookies':True settings = { 'template_path':'template', 'stat ...

  7. codevs 1230【pb_ds】

    题目链接[http://codevs.cn/problem/1230/] 题意:给出n个正整数,然后有m个询问,每个询问一个整数,询问该整数是否在n个正整数中出现过. 题解:很简单的一道题,可以选择用 ...

  8. 【BZOJ 3812】 3812: 主旋律 (容斥原理**)

    3812: 主旋律 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 235  Solved: 196 Description 响应主旋律的号召,大家决定 ...

  9. ARGB 8888 内存大小

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 4字节  argb 各占8个bit

  10. [BZOJ4247]挂饰(DP)

    当最终挂饰集合确定了,一定是先挂挂钩多的在挂挂钩少的. 于是按挂钩从大到小排序,然后就是简单的01背包. #include<cstdio> #include<algorithm> ...