Ошибка сегментирования (образ памяти сброшен на диск)
Я функции для выделения памяти под матрицу размером NxM, освобождения памяти от матрицы, заполнения матрицы по формуле, но выводит ошибку сегментации, можете помочь с решением проблемы
функция main():
int main() {
srand(time(NULL));
//объявляем переиеные и заполняем их случайными числами
int N, M, precision;
N = rand() % 8 + 8;
M = rand() % 8 + 8;
precision = rand() % 6 + 3;
//создаёт матрицу
double **A = start(N, M);
printf("N: %d\nM: %d\n", N, M);
//start(&A, N, M);
printf("%ld\n", sizeof(A));
//заполняем матрицу с помощью формулы
sapol(&A, 7, 8);
//выводим матрицу на экране
for(int i = 0; i< 7; ++i){
for (int j = 0; j< 8; ++j){
printf("%lf ", A[i][j]);
}
putchar('\n');
}
return 0;
}
функции по матрице:
//создаёт матрицу размером NxM
void* start(int N, int M) {
double **A = (double**)malloc(N * sizeof(double*));
if (A == NULL) printf("ERROR: Не удалось выделить память под матрицу\n");
for (int i = 0; i< N; ++i){
*(A+i) = (double*)malloc(M * sizeof(double));
//if (A == NULL) printf("ERROR: Не удалось выделить память под строку матрицы\n");
}
return A;
}
//освобождает память под матрицу
void* free_all(double **A, int N){
for (int i = 0; i < N; ++i)
free(A[i]);
return A;
}
//функция фактариала
double factorial(int n){
long double s = 0;
for (int i = 1; i <= n; ++i){
s *= i;
}
return s;
}
//заполняет матрицу по формуле
void sapol(double ***A, int N, int M){
for (int i = 0; i < N; ++i){
for (int j = 0; j < M; ++j){
if (i == j) ***(A+i*M+j) = 1.0;
else
***(A+i*M+j) = (i>j) ? 1.0/ pow(factorial((double) j), (double) i) : pow(-1.0, (double) i) / pow(factorial((double) j), (double) i);
}
}
}
вывод в консоли:
Ответы (1 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
у вас программе смешан код для двух разных представлений матрицы. Выделяете вы её как массив массивов (double **
), а обращаетсь как к упакованной матрице (A+i*M+j
). Так нельзя.
double **
Если вы решили хранить матрицу в массиве массивов, то все операции парами: два malloc
, два free
, два разыменования указателя:
что | как |
---|---|
тип | item_type ** |
выделение | malloc , malloc |
удаление | free , free |
обращение к элементу | a[i][j] |
#include <stdio.h>
#include <stdlib.h>
void release(int n, double **a) {
for (int i = 0; i < n; ++i) {
free(a[i]);
}
free(a);
}
double **allocate(int n, int m) {
double **a = malloc((size_t)n * sizeof(*a));
if (n > 0 && a == NULL) {
return NULL;
}
for (int i = 0; i < n; ++i) {
a[i] = malloc((size_t)m * sizeof(**a));
if (m > 0 && a[i] == NULL) {
release(i, a);
return NULL;
}
}
return a;
}
void fill(int n, int m, double **a) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
a[i][j] = i + 0.001 * j;
}
}
}
void print(int n, int m, double **a) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (j > 0) {
putchar(' ');
}
printf("%7.3lf", a[i][j]);
}
puts("");
}
}
int main() {
int n, m;
if (scanf("%d%d", &n, &m) != 2) {
exit(1);
}
double **a = allocate(n, m);
if (n > 0 && a == NULL) {
exit(1);
}
fill(n, m, a);
print(n, m, a);
release(n, a);
}
double *
Если вы решили хранить матрицу в одном массиве, в котором строки лежат друг за другом, то все действия под одному:
что | как |
---|---|
тип | item_type * |
выделение | malloc |
удаление | free |
обращение к элементу | a[m * i + j] |
#include <stdio.h>
#include <stdlib.h>
double *allocate(int n, int m) {
double *a = malloc((size_t)(n * m) * sizeof(*a));
if (n > 0 && m > 0 && a == NULL) {
return NULL;
}
return a;
}
void fill(int n, int m, double *a) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
a[m * i + j] = i + 0.001 * j;
}
}
}
void print(int n, int m, double *a) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (j > 0) {
putchar(' ');
}
printf("%7.3lf", a[m * i + j]);
}
puts("");
}
}
int main() {
int n, m;
if (scanf("%d%d", &n, &m) != 2) {
exit(1);
}
double *a = allocate(n, m);
if (n > 0 && m > 0 && a == NULL) {
exit(1);
}
fill(n, m, a);
print(n, m, a);
free(a);
}