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字节对齐的时候,如果取得时候没有声明对齐,那会存在意想不到的效果,哈哈聪明的你可以尝试,反正我是尝试过了。

  • 相关阅读:
    高效的团队必须坚持反馈制度
    项目管理式生活
    用PDCA让工作效率步步高升
    PHP函数:fsockopen简介
    php的getallheaders函数在nginx下失效的解决办法
    getallheaders函数使用方法
    PHP中getenv函数
    PHP获取http请求的头信息实现步骤
    php下获取http状态的实现代码
    PHP获取客户端和服务器端IP
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/7667579.html
Copyright © 2011-2022 走看看