【问题标题】:Conditional jump or move - Valgrind条件跳转或移动 - Valgrind
【发布时间】:2020-07-20 08:49:04
【问题描述】:

我正在编写一个程序,它从文本文件中读取命令并根据它们创建一个广告。使用 valgrind 进行调试时,我收到很多错误,说我正在使用未初始化的变量。其中一个看起来像这样

Conditional jump or move depends on uninitialised value(s)
==5189==    at 0x4838DD0: strcpy (vg_replace_strmem.c:512)
==5189==    by 0x109A28: reduce_space (in /home/jacob/CIS2500/Ass/Ass4/a4q2)
==5189==    by 0x10953A: main (in /home/jacob/CIS2500/Ass/Ass4/a4q2)
==5189==  Uninitialised value was created by a heap allocation
==5189==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==5189==    by 0x109925: reduce_space (in /home/jacob/CIS2500/Ass/Ass4/a4q2)
==5189==    by 0x10953A: main (in /home/jacob/CIS2500/Ass/Ass4/a4q2)

这个错误似乎指向reduce_space函数:

char* reduce_space(char** string){
    char* input = malloc(sizeof(char)*BUFFER);
    char* new=malloc(sizeof(char)*BUFFER);
    strcpy(input, *string);
    int space = 0;
    int i = 0;
    int j = 0;
    int count = 0;


    while(input[i]!='\0'){
        if(input[i]==32){
            j=i+1;
            if(input[j]!='\0'){
                while(input[j]==32&&input[j]!='\0'){
                    i++;
                    j++;
                }
            }
        }
        new[count]=input[i];
        i++;
        count++;
    }
    new[i]='\0';
    strcpy(*string, new);
    free(input);
    free(new);
    return(*string);
}

我真的不明白未初始化的变量在哪里。我声明inputnew 错了吗?

如何调用它的示例:

#include "header.h"

int main(){
    int i;

    FILE* input = fopen("inputfile.input", "r");

    int max = file_size(input);
    char** command = malloc((sizeof(char*)) * max);

    for(i=0;i<max;i++){
        command[i] = malloc((sizeof(char))*BUFFER);
        fgets(command[i], BUFFER, input);
    }

    i = 0;
    while(command[i][0]!='\0'){
        reduce_space(&command[i]);
        i++;
    }
    return(0);
}

【问题讨论】:

  • inputfile.input 中有什么内容? file_size() 是什么?请提供一些失败的示例输入。为了制作minimal reproducible example,您可以硬编码max
  • 您是否包含&lt;stdio.h&gt;&lt;stdlib.h&gt; 等标准标题?您的程序是否在没有警告的情况下编译? "header.h" 是否相关?如果您能给我们一个完全独立的 MRE,不需要我们进行任何编辑或猜测,那将真的很有帮助。谢谢。

标签: c valgrind


【解决方案1】:

fgets() 读取字符串时,它不会删除结尾的\n 换行符。除了最后一行之外,文件中的每一行最后都会有\n,甚至是空行。这意味着command[i][0]!='\0' 不会将它们检测为空,并且循环将持续的时间比应有的时间长。

可能的修复:

  • 检查\n\0
  • 在第一个 for 循环中去除换行符。
  • 如果是i &gt;= max,则停止循环。
  • 合并两个循环。在同一循环中,您可以在 fgets() 之后立即调用 reduce_space()

【讨论】:

    最近更新 更多