Enz*_*ura 2 c segmentation-fault
我正在做一个读取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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,file_to_matrix函数中有两个for循环.一个版本给出了分段错误,另一个版本没有.为什么?有趣的是:如果我启用-O2,两个版本都有效.
使用gcc -std = c11 test.c -o test -g && ./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
???
Run Code Online (Sandbox Code Playgroud)
PS:我在这里发布的代码是另一个代码的一部分,为了简单起见,我从中删除了一些块(例如检查参数的数量,fopen的返回等).我在这里描述的问题也发生在原始代码中.
我认为你正在造成缓冲区溢出
char line[4];
fscanf(path_matr, " %[^\n]", line);
Run Code Online (Sandbox Code Playgroud)
尝试改为
fscanf(path_matr, " %3[^\n]", line);
Run Code Online (Sandbox Code Playgroud)
或以其他方式减轻溢出的可能性.
确保您使用*(unicode 0x2a)而不是?(unicode 0xE2 0x88 0x97)用于分隔符.后者中较大的字符宽度导致scanf()提前终止.(当我在你的问题上复制并粘贴样本输入时,它包括更广泛的字符.)
当你这样做时,最大字段宽度说明符scanf()并不是绝对必要的 - 但我仍然会使用它.
当您优化时增加优化-O2 matrix- 因此程序甚至不会尝试写入它.
PS:你应该检查来自的返回值fopen().