【发布时间】:2020-03-25 09:23:52
【问题描述】:
我有一个简单的 C 代码。
main.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 */
}
cube.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' 之后停止?
【问题讨论】:
-
您忘记验证文件是否已成功打开。
-
C 和 C++ 是不同的语言。除非您询问它们之间的差异,否则不要同时标记两者。
-
在
fopen之后检查stream指针,然后将其传递给cube_initialization() -
@molbdnilo 谢谢,它有帮助。这是因为 valgrind 在自己的环境中运行并且看不到我的文件吗? P.s 对不起 c++ 标签,我认为 valgrind 是一个用于 C/C++ 泄漏检查的工具,我也可以将它标记为 c++。