int input(int *n, int *m, int ***matrix, int *flag) {
char ch;
// Зачем считывать ch, я не понял. Также проверка у вас неправильная.
// scanf возвращает число считанных элементов, вам надо сравнивать это
// число с 2, так как вы считываете n и m.
// if(scanf("%d%d", n,m) != 2 || *n <= 0 || *m <= 0)
// return 0;
if (((scanf("%d%d%c", n,m, &ch)) || (ch != '\n')) && ((*n <= 0) || (*m <=0))){
*flag =0;
// Тут просто сделать return 0;
} else{
// Всё, что ниже, нужно вынести из else блока, а сам else блок убрать
**matrix = (int *)malloc((*n) * sizeof(int*));
for (int i; i < *n; i++ ){
for (int j; j < *m; j++) {
**matrix = (int *)malloc((*n * *m) * sizeof(int));
// if(scanf("%d", &((*matrix)[i][j])) != 1)
// return 0;
if (scanf("%d", matrix[i][j])) {
} else {
*flag =0;
}
}
}
}
// return 1;
return *flag =1;
}
Тут вы используете неверный указатель:
scanf("%d", matrix[i][j]) // так не надо
scanf("%d", &((*matrix)[i][j])) // надо так
scanf("%d", *(*matrix + i) + j) // или так
Не понятно, зачем flag делать указателем, можно объявить его в input, присвоить 1 или 0 и вернуть. Кстати, у вас сравнение неверное, сейчас возвращается всегда 1:
// очевидно, имелось в виду *flag == 1
// Но вообще, можно просто вернуть *flag.
// Или везде, заменить присваивание *flag = что_то на return что_то
return *flag =1;
Так же у вас абсолютно неверно выделяется память:
// Тут каст неверный, должно быть (int**),
// Но в си касты void* к другим типам указателей
// можно опускать. Также нужна лишь одна операция разыменовывания для matrix
**matrix = (int *)malloc((*n) * sizeof(int *));
// Забыли присвоить 0 в i
for (int i; i < *n; i++) {
// А этот цикл надо сделать после выделения памяти для m столбцов
// для ввода данных в выделенную память. Тут тоже забыли присвоить 0 в j.
for (int j; j < *m; j++) {
// Вот тут вы перезаписываете первую строку matrix,
// хотя хотели выделить m столбцов для i строки.
// До перазаписи дело, правда, не дойдёт, так как на предыдущем шаге
// вы сделали два разыменовывания вместо одного и уже словили segfault
**matrix = (int *)malloc((*n * *m) * sizeof(int));
// ...
}
}
Исправляется элементарно:
*matrix = malloc(*n * sizeof(int*));
for (int i = 0; i < *n; i++) {
// *matrix - указатель на двумерный массив,
// *matrix + i - указатель на строку (которая является указателем на одномерный массив),
// *(matrix + i) = ... - присваивание указателю на строку адреса выделенной памяти
*(*matrix + i) = malloc(*m * sizeof(int));
for(int j = 0; j < *m; j++) {
// Ввод данных
}
}
Ну и совет на будущее -
не используйте scanf, хотя проблема сейчас и не в ней. Желательно проверять результат malloc на NULL, чтобы корректно завершать программу в случае нехватки памяти, а не выводить segfault, или не завершать, а просто вызвращать ошибку и продолжать работу дальше. Также не используйте конструкции вида int ***matrix, лучше сделайте функцию, которая принимает n и m и возвращает указатель на матрицу, также сделайте отдельную функцию для ввода значений и вывода.
int** create_matrix(int n, int m);
bool read_matrix(int n, int m, int **matrix);
void write_matrix(int n, int m, int **matrix);
void free_matrix(int n, int m, int **matrix);
Ну и 2 мерный массив можно сделать через одномерный, так будет меньше вызовов malloc, а значит потенциально меньше обращений к ядру. Также, если данные всего двумерного массива будут лежать последовательно, велика вероятность, что в циклах большая часть значений будет браться из кэша, а не из памяти, что даст выигрыш в скорости.
int n = 10, int m = 5;
int *matrix = malloc(sizeof(int) * n * m);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
matrix[i * m + j] // обращение к элементу в i строке в j столбце
}
}
Самое главное - пользуйтесь отладчиком, так вы всегда сможете понять, на какой строке у вас произошла ошибка.