我正在做一个读取3x3矩阵的程序。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int row;
int col;
long **tab;
} matr;
int SIZE = 3;
void *emalloc(size_t size) {
void *memory = malloc(size);
if (!memory) {
fprintf(stderr, "ERROR: Failed to malloc.\n");
exit(1);
}
return memory;
}
void file_to_matrix(FILE *path_matr, matr *m) {
long **matrix = (long**) emalloc(SIZE * sizeof(long*));
for (int i = 0; i < SIZE; i++) matrix[i] = (long*) emalloc(SIZE * sizeof(long));
char line[4];
fscanf(path_matr, " %[^\n]", line);
// This code does not give SEGFAULT
// for (int i = 0; i < SIZE; i++) {
// fscanf(path_matr, "%ld%ld%ld", &matrix[i][0], &matrix[i][1], &matrix[i][2]);
// }
// The code below gives SEGFAULT
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
fscanf(path_matr, "%ld", &matrix[i][j]);
}
}
m->row = SIZE;
m->col = SIZE;
m->tab = matrix;
}
int main(int args, char *argv[]) {
FILE *path_matr = fopen(argv[1], "r");
/*Getting the matrices*/
int n_matr; // Number of matrices
fscanf(path_matr, "%d", &n_matr);
matr *matrices = emalloc(n_matr * sizeof(matr));
for (int i = 0; i < n_matr; i++) {
file_to_matrix(path_matr, &matrices[i]);
}
for (int i = 0; i < n_matr; i++)
free(matrices[i].tab);
free(matrices);
fclose(path_matr);
return 0;
}
请注意file_to_matrix函数中有两个for循环。一个版本给出了分段错误,另一个版本没有。为什么?有趣的是:如果我启用-O2,两个版本都可以。
使用gcc -std = c11 test.c编译-o test -g&amp;&amp; ./test in.txt(gcc version 4.9.2)。
in.txt:
3
∗∗∗
11 12 1444
21 22 23
31 32 33
∗∗∗
11 12 13
21 22 23
31 32 33
∗∗∗
11 12 13
21 22 23
31 31 33
∗∗∗
P.S。:我在这里发布的代码是另一个代码的一部分,为了简单起见,我从中移除了一些块(例如检查参数的数量,fopen&#39; s返回等)。我在这里描述的问题也发生在原始代码中。
答案 0 :(得分:6)
我认为您使用
导致缓冲区溢出char line[4];
fscanf(path_matr, " %[^\n]", line);
尝试更改为
fscanf(path_matr, " %3[^\n]", line);
或以其他方式减轻溢出的可能性。
确保您使用*
(unicode 0x2a)而非∗
(unicode 0xE2 0x88 0x97)作为分隔符。后者中较大的字符宽度会导致scanf()
提前终止。 (当我在你的问题上复制并粘贴样本输入时,它包括更广泛的字符。)
执行此操作时,scanf()
的最大字段宽度说明符并非绝对必要 - 但我仍然会使用它。
当您使用-O2
增加优化时matrix
已经过优化 - 因此程序甚至不会尝试写入。
P.S。:你应该检查fopen()
的返回值。