zoukankan      html  css  js  c++  java
  • 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完全不是自己要的:

    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<h->fieldcount;++i)
    6         {
    7             Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));
    8             printf("a: %d b: %c 
    ", 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字节对齐的时候,如果取得时候没有声明对齐,那会存在意想不到的效果,哈哈聪明的你可以尝试,反正我是尝试过了。

  • 相关阅读:
    让div 充满整个body GIS
    fortuneclient 学习 (客户端接受数据) GIS
    错误 1 error C1083: 无法打开包括文件:“QNetworkProxy”: No such file or directory GIS
    qt fortuneserver 例子学习 ( 给客户端发送消息) GIS
    new操作符(new operator) 和 new操作(operator new)的区别。 GIS
    qt 控件 GIS
    c++ 顺序容器 GIS
    将一个div 分成两列 也可以分成多列 GIS
    控件模板 1
    WPF简单写写。。。
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/7667579.html
Copyright © 2011-2022 走看看