strtok() 包装函数上的 Valgrind 错误

米纳特

我正在尝试创建一个包装函数,strtok()但在对输入字符串进行标记之前,我希望该函数按如下方式处理字符串
1. 如果第一个字符是,然后插入一个字符,例如N第一个字符后跟,
2. 如果,每个字符后面跟着两个字符其他然后N在它们之间插入一个字符 say
3. 如果,;字符相互跟随,则N在它们之间插入一个字符 say
之前尝试过重新分配strncpy()

str = realloc(str, (strlen(array) + 1) * sizeof(char));

我的解决方案:

#define ARRAY_SIZE 100000

int
utils_to_array(char **ret, char *str, char *delim)
{
  char array[ARRAY_SIZE];

  for (int y = 0, z = 0; str[y] != '\0'; y++, z++){ /* LINE 43*/
    if ((str[y] == '\0') && (str[y + 1] == delim[0])){ /* ,*/
      array[z] = 'N';
      ++y;
      ++z;
      array[z] = ',';
    } else if ((str[y] == delim[0]) && (str[y + 1] == delim[0])) { /*,, */
      array[z] = str[y];
      z++;
      array[z] = 'N';
      y++;
      z++;
      array[z] = str[y];
    } else if ((str[y] == delim[0]) && (str[y + 1] == delim[1])) { /* ,; */
      array[z] = str[y];
      z++;
      array[z] = 'N';
      y++;
      z++;
      array[z] = str[y];

    } else {
      array[z] = str[y];
    }
  }

  str = strncpy(str, array, strlen(array)); /* LINE 71 */

  size_t n = 0;
  for (char *p = strtok(str, delim); p ; p = strtok(NULL, delim)) { /* LINE 74 */
    ret[n++] = p;
  }

  return 0;
}

Valgrind 内存测试:

==7534== Conditional jump or move depends on uninitialised value(s)
==7534==    at 0x4C2CAA8: __strlen_sse42 (vg_replace_strmem.c:462)
==7534==    by 0x400BBA: utils_to_array (fxt_utils.c:71)
==7534==    by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534==    by 0x40096E: main (test_parser.c:10)
==7534== 
==7534== Use of uninitialised value of size 8
==7534==    at 0x54DAB1E: strtok (in /usr/lib64/libc-2.17.so)
==7534==    by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534==    by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534==    by 0x40096E: main (test_parser.c:10)
==7534== 
==7534== Use of uninitialised value of size 8
==7534==    at 0x54DAB4E: strtok (in /usr/lib64/libc-2.17.so)
==7534==    by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534==    by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534==    by 0x40096E: main (test_parser.c:10)
==7534== 
==7534== Conditional jump or move depends on uninitialised value(s)
==7534==    at 0x54DAB51: strtok (in /usr/lib64/libc-2.17.so)
==7534==    by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534==    by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534==    by 0x40096E: main (test_parser.c:10)
==7534== 
==7534== 
==7534== HEAP SUMMARY:
==7534==     in use at exit: 18,812 bytes in 7 blocks
==7534==   total heap usage: 7 allocs, 0 frees, 18,812 bytes allocated
==7534== 
==7534== LEAK SUMMARY:
==7534==    definitely lost: 208 bytes in 1 blocks
==7534==    indirectly lost: 0 bytes in 0 blocks
==7534==      possibly lost: 0 bytes in 0 blocks
==7534==    still reachable: 18,604 bytes in 6 blocks
==7534==         suppressed: 0 bytes in 0 blocks
==7534== Rerun with --leak-check=full to see details of leaked memory
==7534== 
==7534== For counts of detected and suppressed errors, rerun with: -v
==7534== Use --track-origins=yes to see where uninitialised values come from
==7534== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)

如果我使用

if (str[0] == ',') { /* LINE 44 */

我收到以下 valgrind 错误

> ==11195== Conditional jump or move depends on uninitialised value(s)
> ==11195==    at 0x400B79: utils_to_array (fxt_utils.c:43)
> ==11195==    by 0x400F1D: parser_gsection_new (fxt_parser.c:115)
> ==11195==    by 0x40096E: main (test_parser.c:10)
> ==11195== 
> ==11195== Conditional jump or move depends on uninitialised value(s)
> ==11195==    at 0x4C2CAA8: __strlen_sse42 (vg_replace_strmem.c:462)
> ==11195==    by 0x400B8D: utils_to_array (fxt_utils.c:72)
> ==11195==    by 0x400F1D: parser_gsection_new (fxt_parser.c:115)
> ==11195==    by 0x40096E: main (test_parser.c:10)
> ==11195== 
> ==11195== 
> ==11195== Process terminating with default action of signal 11 (SIGSEGV)
> ==11195==  Bad permissions for mapped region at address 0x1FFEFFFD6A
> ==11195==    at 0x1FFEFFFD6A: ???
> ==11195==    by 0x1FFEFFFD7F: ???
> ==11195==    by 0x2C4E2C4E2C4DFFFF: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==    by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== 
> ==11195== HEAP SUMMARY:
> ==11195==     in use at exit: 18,812 bytes in 7 blocks
> ==11195==   total heap usage: 7 allocs, 0 frees, 18,812 bytes allocated
> ==11195== 
> ==11195== LEAK SUMMARY:
> ==11195==    definitely lost: 208 bytes in 1 blocks
> ==11195==    indirectly lost: 0 bytes in 0 blocks
> ==11195==      possibly lost: 0 bytes in 0 blocks
> ==11195==    still reachable: 18,604 bytes in 6 blocks
> ==11195==         suppressed: 0 bytes in 0 blocks
> ==11195== Rerun with --leak-check=full to see details of leaked memory
> ==11195== 
> ==11195== For counts of detected and suppressed errors, rerun with: -v
> ==11195== Use --track-origins=yes to see where uninitialised values come from
> ==11195== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

字符串输入示例:

,, 126HC:\用户\ 410239个\文件\工作\查询\拉帕零件17-08-2017 \ AA00001106762_Ao_REINFORCEMENT \ AA00001106762_AO_REINFORCEMENT.stp,30HAA00001106762_AO_REINFORCEMENT,22HAutodesk发明者2016,7Hunknown,32,38,7,99,15,1。 ,2,2HMM,1,0.08,15H20180314.163749,0.01,10000.,4Hnone,4Hnone,11,0,15H20170818.085306;

米纳特

由于strsep()可以处理空字段,因此当字段为空时不再需要插入 N。这就是我使用@rici 发送的 linux 手册页和链接解决问题的方法:
https : //github.com/freebsd/freebsd/blob/master/sys/libkern/strsep.c
是否有 strsep() 的 Windows 变体

int
utils_to_array(char **ret, char *str, char *delim)
{
  size_t count = 0;
  char *tok;

  while((tok = strsep(&str, delim)) && count < PARAM_MAX)
        ret[count++] = tok;

  return 0;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档