Как организовать работу двух динамических массивов используя malloc?

При попытке организации двух двумерных динамических массивов возникает ошибка 0xC00000FD - переполнение стека, что не так и можно ли создавать динамический массив с помощью функций(закомментированная часть)
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>

/*void arr_cr( int **a , int n, int m){
    int i,j;
    a=(int **)malloc(n*sizeof(int *));
    for( i=0 ; i < m ; i++)
        a[i]=(int *)malloc(sizeof(int));
}
*/
void arr_in( int **a, int n, int m){
    int i,j;
    for( i=0 ; i < n ; i++)
    for( j=0 ; j < m ; j++)
        a[i][j]= rand() % 300 +100;
}

void arr_out( int **a, int n, int m){
    int i,j;
    for( i=0 ; i < n ; i++,puts(""))
    for( j=0 ; j < m ; j++)
        printf("%3i",a[i][j]);
}

int main(){
    int i,j,n,**X,**Y;

    X=(int **)malloc(10*sizeof(int *));
    for( i=0 ; i < 8 ; i++)
        X[i]=(int *)malloc(sizeof(int));

    Y=(int **)malloc(10*sizeof(int *));
    for( i=0 ; i < 12 ; i++)
        X[i]=(int *)malloc(sizeof(int));

    //arr_cr(X,10,8);
    //arr_cr(Y,10,12);
    arr_in(X,10,8);
    arr_in(Y,10,12);
    arr_out(X,10,8);
    arr_out(Y,10,12);

return 0;
}
  • Вопрос задан
  • 97 просмотров
Решения вопроса 1
@res2001
Developer, ex-admin
Добавлю ко всему выше написанному: подобное использование двумерных массивов убивает производительность, т.к. вместо одного чтения памяти происходит 2, а кроме того весь массив разбит на много маленьких кусков, которые лежат в разных местах памяти - кэш процессора используется не эффективно. В нагруженных приложениях это будет сказываться.
Правильнее использовать двумерный массив выделенный одним куском и пересчитывать индексы в ручную:
int *a = malloc(sizeof(int) * n * m);
for(int i=0; i < n; ++i)
  for(int j=0; j < m; ++j)
    *(a + i * m + j) = 0;

Это стандартный вариант использования двумерного массива, который будет работать везде и на С++ то же.

Что бы избежать пересчета индексов (например когда массивы трехмерные или больше) можно использовать промежуточный "указатель на массив переменной длины" (правда это будет работать только на gcc/clang и в С++ работать не будет, только С99+). Подробно расписывать не буду, т.к. тут важно понимание. Если будет интересно в интернете информацию по VLA найдете.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
Надо так:
void arr_cr( int ***a , int n, int m){
    int i,j;
    a*=(int **)malloc(n*sizeof(int *));
    for( i=0 ; i < n ; i++)
        (a*)[i]=(int *)malloc(m*sizeof(int));
}


У вас везде напутано - вы создаете n/10/10 int*, а потом заполняете их циклом до m/8/12. Выделили 10 элементов, заполнили 8 или 12. Непорядок.

И когда вы выделяете память под строку массива в цикле, вы должны не sizeof(int) памяти выделять, а в m/8/12 раз больше - вы же под всю строку память выделять должны.

edit: еще не заметил, что массив передается по значению. Надо передавать int***.
Ответ написан
Комментировать
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Y=(int **)malloc(10*sizeof(int *));
    for( i=0 ; i < 12 ; i++)
        X[i]=(int *)malloc(sizeof(int));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы