【问题标题】:A random character showing up at the end of a C array出现在 C 数组末尾的随机字符
【发布时间】:2014-10-22 05:10:47
【问题描述】:

我有代码:

else if ((strtolnum=(strtol(&oldline[b+1],NULL,10)))>0)
        {
            char* excl = malloc(3*sizeof(char));
            excl[0]=oldline[b];
            excl[1]=oldline[b+1];
            for (int j = 0; j<strtolnum; j++)
            {
                llist=llist->nextcmd;
            }
            struct token *p1;
            struct token *save1 = llist->cmmd;
            char *arra1 = malloc(sizeof(char));
            memset(arra1, '\0', 1);
            for (p1 = llist->cmmd;  p1 != NULL;  p1 = p1->next) {
                arra = realloc(arra1, strlen(arra1)+strlen(p1->text)+2);
                strcat(arra, p1->text);
                if (p1->next!=NULL)
                {
                    strcat(arra1, " ");
                }//   printing token and type
            }
            printf("%s excl\n", excl); //Line 137
            oldline=strreplace(oldline,excl,arra1); //Line 138
            llist->cmmd=save1;
            for (int j = 0; j<(f-strtolnum); j++)
            {
                llist=llist->nextcmd;
            }
            *status=1;
            size_t a = sizeof(excl);
            memset(excl,'\0', a);
        }

代码应该完成的是获取前面有感叹号部分的行的第一个整数,例如!3,并将其放入 excl(然后执行其他工作正常的事情)。

但是,当我多次运行循环时,我发现 excl 的末尾通常有一个随机字符,例如当我尝试 printf 时它显示为“!3e”。 Valgrind 显示以下错误:

==24878== Conditional jump or move depends on uninitialised value(s)
==24878==    at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so)
==24878==    by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so)
==24878==    by 0x40130F: hExpand (Lex1.c:137)
==24878==    by 0x400B6B: main (mainLex.c:27)
==24878== 
==24878== Conditional jump or move depends on uninitialised value(s)
==24878==    at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24878==    by 0x4020D7: strreplace (Lex1.c:562)
==24878==    by 0x40132C: hExpand (Lex1.c:138)

显然,循环经过一次后, excl 就被初始化了。怎么了?

更多信息,cmmd 是 token 类型的数据结构,llist 是包含 token 的全局静态数据结构。

【问题讨论】:

  • 你还没有终止excl字符串; malloc() 返回随机垃圾。
  • 这些行:size_t a = sizeof(excl); memset(excl,'\0', a);将始终将 excl 指针的 4 个字节设置为 0x00。这会导致内存泄漏,并且 excl 指向内存中的第一个字节。如果您实际上试图清除分配内存中的值(在所有情况下恰好是 3 个字节),那么也许使用:memset( excl, '\0', 3 );
  • @user3629249:它不会将指针本身设置为零;它将指针指向的内存设置为零。要将指针归零,您必须调用 memset(&amp;excl, '\0', a);

标签: c arrays data-structures initialization valgrind


【解决方案1】:

您还没有以 null 终止 excl 字符串; malloc() 返回随机垃圾。您可能会考虑添加:

excl[2] = '\0';

你也践踏了出界:

size_t a = sizeof(excl);
memset(excl,'\0', a);

您将 4 或 8(32 位或 64 位)分配给 a,然后写入那么多字节,但您只为 excl 分配了 3 个字节。

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2020-12-22
    • 2022-01-21
    • 2011-09-16
    • 2023-03-17
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多