【问题标题】:Array access error in CC中的数组访问错误
【发布时间】:2014-10-01 08:45:40
【问题描述】:

我的代码中不断出现 valgrind 错误,我不知道如何修复它。 :/ 这个想法是,无论输入中的 2 个或多个单词/字母之间有多少制表符/空格,在输出中它应该只有一个空格。 例如:

a    b   c d -> a b c d

代码:

char* echo(char* in) {
    char buffer[256];
    int incounter=0, buffcounter=0;

    while(incounter<(strlen(in))) {
        if(in[incounter] == ' ' || in[incounter] == '\t') incounter++;
        else if(in[incounter] != ' ' && in[incounter] != '\t') {
            while(in[incounter] != ' ' && in[incounter] != '\t') {
                buffer[buffcounter] = in[incounter];  //53
                incounter++;
                buffcounter++;              
            }           
            buffer[buffcounter] = ' ';
            buffcounter++;
        }
    }
    char* out = buffer;
    return out;
}

错误:

==20521== Conditional jump or move depends on uninitialised value(s)
==20521==    at 0x4010B4: echo (hhush.c:53)
==20521==    by 0x4021CA: readCommand (hhush.c:327)
==20521==    by 0x402538: main (hhush.c:371)
==20521==  Uninitialised value was created by a stack allocation
==20521==    at 0x402017: readCommand (hhush.c:301)
==20521== 
==20521== Conditional jump or move depends on uninitialised value(s)
==20521==    at 0x4010CE: echo (hhush.c:53)
==20521==    by 0x4021CA: readCommand (hhush.c:327)
==20521==    by 0x402538: main (hhush.c:371)
==20521==  Uninitialised value was created by a stack allocation
==20521==    at 0x402017: readCommand (hhush.c:301)

这就是我现在的位置,仍然是同样的错误

char* echo(char* in,char* buffer){
    size_t inlen=strlen(in);
    int incounter=0,buffcounter=0;
    while(incounter<inlen){
        if(in[incounter]==' '||in[incounter]=='\t')incounter++;
        else{
            while(in[incounter]!=' '&&in[incounter]!='\t'){
                buffer[buffcounter]=in[incounter];
                incounter++;
                buffcounter++;              
            }           
            buffer[buffcounter]=' ';
            buffcounter++;
        }   
    }
    return buffer;
}

我称之为:

char input[256];
fgets(input,sizeof(input),stdin);
...
char buffer[256];
printf("%s\n",echo(input,buffer));

【问题讨论】:

  • 是什么让你认为 strlen(in)
  • 函数永远不会被更大的输入调用
  • 为什么每次循环迭代都计算strlen(in)?它不会改变。 OTAH,我觉得这部分可以直接去掉if(in[incounter] != ' ' &amp;&amp; in[incounter] != '\t')
  • 则不会跳过空格
  • 内部while循环可以在输入字符串的末尾运行

标签: c arrays error-handling char


【解决方案1】:
 char* out=buffer;
 return out;
}

不要返回指向具有自动存储持续时间的数组的指针(此处为 buffer 数组)。如果指针值被访问,它会调用未定义的行为,因为自动对象在声明它们的块退出时被丢弃(这里是echo 函数返回时)。

【讨论】:

  • @slyr 要快速检查它是否修复了 valgrind 消息,只需在数组声明中添加 static 说明符。
  • @slyr 在这种情况下,我们还需要查看如何调用echo 以及如何声明它的参数。
  • 我猜这是 valgrind 发现的,但程序中似乎还有其他几个错误,不仅仅是这个。
【解决方案2】:

如果你想在函数之外使用缓冲区,那么你应该将分配的缓冲区传递给函数。

void echo(char *in, char *buffer)
{
    //do stuff
}

这样您就不会尝试访问超出范围的内存。

然后你就可以使用这个函数了

char buffer[256];
echo(string, buffer);

缓冲区现在应该包含您编辑的字符串。

【讨论】:

    【解决方案3】:

    这条消息:

    ==20521== Conditional jump or move depends on uninitialised value(s)
    ==20521==    at 0x4010B4: echo (hhush.c:53)
    ==20521==  Uninitialised value was created by a stack allocation
    ==20521==    at 0x402017: readCommand (hhush.c:301)
    

    告诉您第 53 行的 ifwhile 测试取决于未初始化的数据。有问题的数据是在第 301 行分配的。通过查看这些行,您应该能够知道发生了什么,但看起来您是在 readCommand 的堆栈上分配一个数组,然后将其传递给 @ 987654325@ 作为参数,没有在数组中放入任何东西。因此,您的“我用代码调用它”实际上类似于:

    char input[256];
    fgets(input,sizeof(input),stdin);
    ...
    char buffer[256];
    printf("%s\n",echo(buffer));
    

    而你并没有通过你认为你正在通过的东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 2015-11-09
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多