• gcc4.8.5下strncpy的坑


       一直以来都很中意strncpy,没想到会在升级gcc版本后出现巨坑。

       使用场景是对串a开头几个字符做删除处理,假如有以空格开始的串,要求去掉空格,一般是自身拷贝,相当于对数组成员进行移位。

    strncpy(a, a+n, strlen(a)-n)

    像这个情况,在gcc4.8.5版本下,编译成32位及64位的应用,字符拷贝就会出问题。原因可能是gcc4.8.5的优化出现的问题。

    centos7.4,gcc4.8.5实测如下:

    int main ()
    {
      char str0[10]="123456789";
      char str1[512]= " IIP:123.112.154.118;LIP:192.168.118.107;MAC:54EE750B1713;HD:TF655AY91GHRVL23466SDGG;PCN:XXJSB-ZHUANGSHUANG;CPU:BFEBFBFF004065";
      char str2[240];
      char str3[40];
      int len = strlen(str1);
      /* copy to sized buffer (overflow safe): */
      strncpy (str2, str1+1, len-1);
      strncpy(str1, str1+1, len-1);
      str1[len-1] = 0;
    
      str3[5] = '';   /* null character manually added */
    
      puts(str1);
      puts (str2);
      puts (str3);
    
      return 0;
    }

    编译

     gcc -m32 test.cpp -o test

    运行结果:

     64位的测试用例:

    int main ()
    {
      char str0[11]="123456789";
      char str1[512]= " IIP:123.112.154.118;LIP:192.168.118.107;MAC:54EE750B1713;HD:TF655AY91GHRVL23466SDGG;PCN:XXJSB-ZHUANGSHUANG;CPU:BFEBFBFF004065";
      
      char str2[540];
      char *str3 = str2+1;
      int len = strlen(str1);
      printf("str0    [%p] str1[%p]str3[%p]
    ", str0, str1, str3);
      strncpy (str3, str1, len);
      strncpy (str3, str3+1, len-1);
      strncpy(str1, str1+1, len-1);
      str1[len-1] = 0;
    
      puts(str1);
      puts (str2);
      puts (str3);
    
      return 0;
    }
    

    编译:

    gcc test.cpp -o test
    

    运行结果:

     可见,不管是32位还是64位,都存在问题。

    修改方案是使用 memmove替代strncpy

    strncpy(str2, str1+1, len-1);
    //strncpy(str1, str1+1, len-1);
    memmove(str1, str1+1, len-1);
    

      

    非自身拷贝场景是正常的,比如把串a内容拷贝给串b,是正常的

    strncpy(b, a, sizeof(b)-1);
    

      

  • 相关阅读:
    .net大文件上传
    java文件上传和下载
    文件上传系统
    plupload上传大文件
    代码坏味道之夸夸其谈的未来性
    freemarker中的substring取子串
    【翻译自mos文章】在Oracle GoldenGate中循环使用ggserr.log的方法
    3种浏览器性能測试
    SDUTOJ 2772 KMP简单应用
    C++库研究笔记--用__attribute__((deprecated)) 管理过时代码
  • 原文地址:https://www.cnblogs.com/ikel/p/13501856.html
Copyright © 2020-2023  润新知