Segmentation fault при внесении данных в статичный массив и при не выполнении условия if
Программа на вход принимает первым аргументом - метод создания массива. Вторым - размер массива и его значения построчно.
#include <stdio.h>
#include <stdlib.h>
#define NMAX 100
int input(int **a, int n, int m);
void output(int **a, int n, int m);
int input_arr(int *p);
int input_size_arr(int *m, int *n);
int main() {
int flag = 0;
int **data = NULL;
int p, n, m;
if (input_arr(&p) == 0) {
if (input_size_arr(&n, &m) == 0) {
if (p == 1) {
static int data_stat[NMAX][NMAX];
data = data_stat;
}
if (p == 2) {
data = (int**)malloc(m*sizeof(int*));
for (int i = 0; i < n; i++) {
data[i] = (int*)malloc(n*sizeof(int*));
}
if (data == NULL) {
printf("n/a");
flag = 1;
}
}
if (p == 3) {
data = (int**)calloc(m, sizeof(int*));
for (int i = 0; i < n; i++) {
data[i] = (int*)calloc(n, sizeof(int*));
}
if (data == NULL) {
printf("n/a");
flag = 1;
}
}
if (p == 4) {
data = (int**)realloc(data, m*sizeof(int*));
for (int i = 0; i < n; i++) {
data[i] = (int*)realloc(data[i], n*sizeof(int*));
}
if (data == NULL) {
printf("n/a");
flag = 1;
}
}
}
if (flag == 0) {
if (input(data, n, m) == 0) {
output(data, n, m);
}
}
}
for (int i = 0; i < m; i++) {
free(data[i]);
}
free(data);
return 0;
}
int input_arr(int *p) {
int flag = 0;
char c;
if (scanf("%d%c", p, &c) != 2 || c != '\n') {
printf("n/a");
flag = 1;
} else if ((*p > 4 || *p < 1) && flag == 0) {
printf("n/a");
flag = 1;
}
return flag;
}
int input_size_arr(int *m, int *n) {
int flag = 0;
char c;
if (scanf("%d%c", m, &c) != 2 || c != ' ') {
printf("n/a");
flag = 1;
} else if ((scanf("%d%c", n, &c) != 2 || c != '\n') && flag == 0) {
printf("n/a");
flag = 1;
} else if ((*n > 100 || *m > 100 || *n < 2 || *m < 2) && flag == 0) {
printf("n/a");
flag = 1;
}
return flag;
}
int input(int **a, int n, int m) {
char c;
int i = 0;
int i2 = 0;
int flag = 0;
while (i2 < m) {
while (i < n-1) {
if (flag == 1) break;
if (scanf("%d%c", &a[i2][i], &c) != 2 || (c != ' ')) {
printf("n/a");
flag = 1;
} else {
i++;
}
}
i = 0;
if (flag == 0) {
if (scanf("%d%c", &a[i2][n-1], &c) != 2 || c != '\n') {
printf("n/a");
flag = 1;
}
}
i2++;
}
return flag;
}
void output(int **a, int n, int m) {
int i = 0;
int i2 = 0;
int min = 99999999;
int max = 0;
while (i2 < m) {
while (i < n-1) {
printf("%d ", a[i2][i]);
i++;
}
printf("%d", a[i2][n-1]);
printf("\n");
i = 0;
i2++;
}
i = 0;
i2 = 0;
while (i2 < m) {
while (i < n) {
if (a[i2][i] > max) max = a[i2][i];
i++;
}
printf("%d ", max);
i = 0;
i2++;
max = 0;
}
printf("\n");
i2 = 0;
i = 0;
while (i2 < m) {
min = 99999999;
while (i < n) {
if (a[i][i2] < min) min = a[i][i2];
i++;
}
if (i2 < m-1) printf("%d ", min);
i = 0;
i2++;
}
printf("%d", min);
}
В первом случае ошибка вылезает при занесении данных в статичный массив, за это отвечает функция input(int **a, int n, int m). При работе с выделением динамической памяти все работает, а с массивом нет. Объявляется он в main и присваивается указателю в строке 16. Пробовал выносить за main, и делать static int.
Во втором случае, в функции input_size_arr(int *m, int *n) идет проверка в строке 82 на размер введенных значений, если условие else if выполняется, то выдает segmentation fault, вместо вывода на экран n/a по условию.
Ответы (1 шт):
Тип static int data_stat[NMAX][NMAX]; несовместим с int **data = NULL;. Математика вычисления позиций элементов совсем разная. data_stat содержит только типы int, а data - это массив указателей на массивы int.
& data_stat[i][j] == & data_stat[0][0] + i * sizeof ( int[NMAX])
+ j * sizeof(int)
& data[i][j] == data[i] + j * sizeof(int)
При присваивании указателей data = data_stat; и попытке доступа к элементам происходит ошибка неправильного доступа к памяти, так как компилятор думает, что там указатель, а там числа.
Решением будет не использовать статический массив static int data_stat[NMAX][NMAX];. А всегда создавать с помощью malloc.
Ещё у вас ошибка выделения памяти. Вы выделяете память под массив указателей, а надо под числа. А также выделяете память под m строк, а указателей пишете n штук.
data = (int**)malloc(m*sizeof(int*));
for (int i = 0; i < n ; i++) {
data[i] = (int*)malloc(n*sizeof(int * ));
v v
for (int i = 0; i < m ; i++) {
data[i] = (int*)malloc(n*sizeof(int ));