【问题标题】:How do I get rid of this Valgrind warning and use argv[]?如何摆脱这个 Valgrind 警告并使用 argv[]?
【发布时间】:2021-11-08 13:50:03
【问题描述】:

我对 C 编程很陌生,我正在编写这个程序以读取文件并打印到自动对齐的表格中。一切正常,但我收到 Valgrind 警告,指出条件跳转或移动取决于未初始化的值。我还需要能够传入任何 .txt 文件,而不仅仅是特定的 .txt 文件。我知道我可以使用 argv 但不知道如何在函数中使用它而不是在 main 中调用它。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// constant to store the maximum size of the records that can be read from the file

enum
{
    // update MAX_SIZE to if the number of rows is more than 1000
    MAX_SIZE = 1024
};

// structure to store a record from the file
typedef struct
{
    char define[20];
    char octal[26];
    char description[1000];
} Record;

// string to store the header of the table
char header1[20], header2[20], header3[20];

// function to read the file and return the maximum length of the descriptions read from the file
void readFile(Record rec[], int *size,int *length, int *length1, int *length2)
{
    int i = 0;
    int maxLength,maxLength1,maxLength2=0;
    // open a file for input
    FILE *fp = fopen("input2.txt", "r");

    // check if the file opened successfully
    if (fp == NULL)
    {
        printf("File could not be opened!");
        exit(1);
    }

    
    // read the file
    // first we read the header of each column from the file
    fscanf(fp, "%s %s %s\n", header1, header2, header3);

    // now we read each record from the file
    while (fscanf(fp, "%20s ", rec[i].define) == 1)
    {
        fscanf(fp, "%20s '%[^']'", rec[i].octal, rec[i].description);

        // find the length of the description and update the 'maxLength'
        if(strlen(rec[i].description) > maxLength)
        {
            maxLength = strlen(rec[i].description);
        }
        else if(strlen(rec[i].octal) > maxLength1)
        {
            maxLength1 = strlen(rec[i].octal);  
        }
        else if(strlen(rec[i].define) > maxLength2)
        {
            maxLength2 = strlen(rec[i].define);
        }
        
        // increment the value of i
        i++;
    }

    printf(" Length: %d \n", maxLength);    

    // close the input file
    fclose(fp);

    // update the number of records read from the file
    *size = i;    
    *length = maxLength;
    *length1 = maxLength1;
    *length2 = maxLength2;
}

void printTable(Record rec[], int size, int length, int length1, int length2)
{
    if(length2 >= 15)
    {
        for (int i = 0; i < length+length1+length2+17; i++)
            printf("-");

        printf("\n| %-*s | %*s | %-*s |\n", length2,header1, length1, header2,  length, header3);

        for (int i = 0; i < length+length1+length2+17; i++)
            printf("-");
        printf("\n");

        // print the table data
        for (int i = 0; i < size; i++)
            printf("| %-*s | %10s | %-*s |\n",length2, rec[i].define,  rec[i].octal, length, rec[i].description);

        // print the footer
        for (int i = 0; i < length+length1+length2+17; i++)
            printf("-");
        printf("\n");
    }
    else
    {
        printf("length: %d \n", length2);
        // print the header of the table
        for (int i = 0; i < length+length1+length2+10; i++)
            printf("-");

        printf("\n| %-*s | %*s | %-*s |\n", length2,header1, length1, header2,  length, header3);

        for (int i = 0; i < length+length1+length2+10; i++)
            printf("-");
        printf("\n");

        // print the table data
        for (int i = 0; i < size; i++)
            printf("| %-*s | %*s | %-*s |\n",length2, rec[i].define, length1, rec[i].octal, length, rec[i].description);

        // print the footer
        for (int i = 0; i < length+length1+length2+10; i++)
            printf("-");
        printf("\n");
    }
}

// driver function
int main()
{
    // create an array of recors of MAX_SIZE
    Record recs[MAX_SIZE];
    // initialize size of recs to zero
    int size = 0;
    int length=0;
    int length1=0;
    int length2=0;

    // call readFile() function to read data from the file and update the size of recs
    readFile(recs, &size,&length,&length1,&length2);
     
    // call printTable() function to print the table in a well-formatted manner
    printTable(recs, size, length,length1,length2);

    return 0;
}

Valgrind 警告:

==1821== Memcheck, a memory error detector
==1821== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1821== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1821== Command: ./main input2.txt
==1821== 
==1821== Conditional jump or move depends on uninitialised value(s)
==1821==    at 0x10896F: readFile (main.c:50)
==1821==    by 0x108E17: main (main.c:147)
==1821== 
==1821== Conditional jump or move depends on uninitialised value(s)
==1821==    at 0x1089C2: readFile (main.c:54)
==1821==    by 0x108E17: main (main.c:147)

【问题讨论】:

  • 代码中另一个可能的疏忽是maxLength 被定义为int,但与size_t 相比。最好也将 size_t 用于 maxLength 变量。
  • 除了maxLengthmaxLength1 没有被初始化并且是错误的类型以获取strlen() 返回值size_t 如@Cheatah 提到的那样,您可能仍然会看到此错误来自 valgrind,因为整个 rec[i].description 字段在被 strlen() 遍历之前没有在读取时初始化;如果是这种情况,您需要将main() 中的Record recs[MAX_SIZE]; 更改为Record recs[MAX_SIZE] = {0}; 以初始化所有记录结构内存。

标签: c file valgrind argv


【解决方案1】:

不要使用这样的声明:

int maxLength,maxLength1,maxLength2=0;

这是危险且难以阅读的,因为maxLengthmaxLength1 不会被初始化为0。

而是在单独的行上声明每个变量,这样更易​​读:

int maxLength = 0;
int maxLength1 = 0;
int maxLength2 = 0;

【讨论】:

    【解决方案2】:

    它试图告诉你maxLengthmaxLength1 是未初始化的变量。

    你有这行声明:

    int maxLength,maxLength1,maxLength2=0;
    

    但只有maxLength2 在该语句中被初始化为零。其他两个变量的值未定义。

    因此,当代码到达第 50 行或第 54 行并进行此比较时:

        if(strlen(rec[i].description) > maxLength){
    

    不确定maxLength 应该是什么。

    【讨论】:

    • 建议:也许 OP 打算写类似:int maxLength,maxLength1,maxLength2; maxLength = maxLength1 = maxLength2 = 0;?尽管就个人而言,我认为最好将每个声明/初始化放在单独的行中。
    • 另一种选择:int maxLength = 0, maxLength1 = 0, maxLength2 = 0;
    【解决方案3】:

    int maxLength,maxLength1,maxLength2=0; 未初始化 maxLengthmaxLength1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2022-11-16
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      相关资源
      最近更新 更多