c - 为什么 Valgrind 提示 fgets?

标签 c valgrind fopen

我有一个简单的 C 代码。

ma​​in.c

int main() {
    FILE *stream = fopen("../input.txt", "r");
    cube test_cube;
    cube_initialization(&test_cube, stream);

/* and some code with free memory which is not needed to understand the situation */

}

立方体.c

/* just the function valgrind complains about */

void cube_initialization(cube *cube, FILE *input_file) {
    int side_length;
    char buffer[BUF_SIZE];
    char waste_buffer[BUF_SIZE];


    fgets(buffer, BUF_SIZE, input_file);
    fgets(waste_buffer, BUF_SIZE, input_file); /* empty line */
    side_length = (int) strtol(buffer, NULL, 10);
    cube->side_length = side_length;
    cube->cube_array = malloc(side_length * sizeof(int **));
    int z;
    for (z = 0; z < side_length; z++) {
        cube->cube_array[z] = malloc(side_length * sizeof(int *));
        int y;
        for (y = 0; y < side_length; y++) {
            cube->cube_array[z][y] = malloc(side_length * sizeof(int));
        }
    }
}

和 valgrind 输出

==8251== Invalid read of size 4
==8251==    at 0x48F3727: fgets (iofgets.c:47)
==8251==    by 0x1093C2: cube_initialization (cube.c:11)
==8251==    by 0x10928D: main (main.c:11)
==8251==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8251== 
==8251== 
==8251== Process terminating with default action of signal 11 (SIGSEGV)
==8251==  Access not within mapped region at address 0x0
==8251==    at 0x48F3727: fgets (iofgets.c:47)
==8251==    by 0x1093C2: cube_initialization (cube.c:11)
==8251==    by 0x10928D: main (main.c:11)
==8251==  If you believe this happened as a result of a stack
==8251==  overflow in your program's main thread (unlikely but
==8251==  possible), you can try to increase the size of the
==8251==  main thread stack using the --main-stacksize= flag.
==8251==  The main thread stack size used in this run was 8388608.
==8251== 
==8251== HEAP SUMMARY:
==8251==     in use at exit: 0 bytes in 0 blocks
==8251==   total heap usage: 1 allocs, 1 frees, 488 bytes allocated
==8251== 
==8251== All heap blocks were freed -- no leaks are possible
==8251== 
==8251== For lists of detected and suppressed errors, rerun with: -s
==8251== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

我不明白为什么 Valgrind 提示 fgets()。我从文件中读取数据并使用带有指向大缓冲区 (256) 的指针的 fgets 但它只需要我读取大约 1-6 个符号的短行(我需要 fgets 因为它在找到时停止 '\n ' 在行尾)。也许问题在于 fgets() 试图读取 256 个符号的行,但它在 1-5 和 '\n' 之后停止?

最佳答案

Valgrind 提示非法地址 0x0 访问:

Address 0x0 is not stack'd, malloc'd or (recently) free'd

在您的 fgets() 调用中

fgets(buffer, BUF_SIZE, input_file);

buffer 参数很好,因为它是在堆栈中分配的。唯一负责的可能是来自 main()input_file 参数。该参数是从 fopen() 调用中获得的流。在传递给 cube_initialization() 之前你没有检查它!

检查一下,然后理解为什么返回NULL(可能你试图打开一个不存在的路径)。

int main() {
    FILE *stream = fopen("../input.txt", "r");
    cube test_cube;
    if( stream != NULL )
    {
        cube_initialization(&test_cube, stream);

        /* Continue execution*/
    }
}

关于c - 为什么 Valgrind 提示 fgets?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60845970/

相关文章:

buffer-overflow - 缓冲区溢出漏洞

c - 嵌入式系统中封装的意图

c - Valgrind 和 "#pragma pack(2)"

c++ - 检测到 'memory leak' 时,valgrind 中的实际指针是什么?

无法将 char 数组(文件名)传递给 fopen(file,r)

c - 检索/比较文件中的字符串与用户文本

c - 推送全局链表时出错*有时(随机)*

c - "int i = 0"中的操作数

c - 在C中使用calloc为char数组分配内存时如何避免 'possibly lost'内存

php - 为什么 PHP 7.2 fopen(/tmp, a) 不写入文件?