c: динамическое выделение трехмерного массива, когда 1 измерение неизвестно - PullRequest
3 голосов
/ 23 января 2012

Я пытаюсь динамически выделить трехмерный массив с этими параметрами: 1) Первые 2 измерения, которые я знаю, могут быть определены как константы (ACOUNT и BCOUNT). Третий должен быть решен во время выполнения. 2) Я хочу иметь возможность обратиться к массиву, используя: arr [i] [j] [k] = n; 3) Я хочу избежать смерти на миллион + mallocs

Итак, в следующем коде первая часть, использующая «* arr», прекрасно работает, а вторая часть, использующая «* brr», встречает печальный конец. Есть ли способ достичь этих параметров, используя какое-то волшебное зелье звездочек?

(Я компилирую с использованием VS2010 C ++, таким образом, это отвратительные кастинги.)

#define ACOUNT 9000
#define BCOUNT 195
#define CCOUNT 8

short (*arr)[BCOUNT][CCOUNT];
short (*brr)[ACOUNT][BCOUNT];

void main(void)
{

    arr = (short (*)[BCOUNT][CCOUNT] )  malloc( (unsigned long) ACOUNT * BCOUNT *CCOUNT * sizeof(short));

        for (int j = 0; j < ACOUNT; ++j)
            for (int k = 0; k < BCOUNT; ++k)
                for (int m = 0; m < CCOUNT; ++m)
                    arr[j][k][m] = j + k + m;

    // still alive here

    brr = (short (*)[ACOUNT][BCOUNT] )  malloc( (unsigned long) ACOUNT * BCOUNT *CCOUNT * sizeof(short));

        for (int j = 0; j < ACOUNT; ++j)
            for (int k = 0; k < BCOUNT; ++k)
                for (int m = 0; m < CCOUNT; ++m)
                    brr[j][k][m] = j + k + m;

         // error: unhandled exception ...access violation... etc
}

Ответы [ 2 ]

0 голосов
/ 24 января 2012

Извинения, я понял после того, как опубликовал это ваше отвращение к чрезмерным выражениям malloc (или calloc). Код использует чрезмерные числа этого оператора, что потребует чрезмерной очистки (свободный оператор). Я оставлю пост на случай, если вы сможете использовать какую-то его часть. Ryk

Вот некоторый код, который иллюстрирует динамическое создание и выделение пространства для матриц. Они также показывают шаблон для последовательных матриц большего размера. Обратите внимание, что список аргументов включает только желаемый размер (порядок) каждого индекса; то есть строка (r), затем c, r (столбец, строка), затем p, c, r (страница, столбец, строка) и так далее. Обратите внимание, что эти функции также заменяют malloc на calloc, просто предпочтение. С Уважением, Ryk

double * Create1D(int r)
{   
    double *space; 
    double *arr;

    space = calloc(r*sizeof(double), sizeof(double));
    arr   = calloc(sizeof(double), sizeof(double));
    arr = (double *)space;

    return arr;
}

double ** Create2D(int c, int r)
{   
    double *space; 
    double **arr;
    int    y;

    space   = calloc(c*r*sizeof(double), sizeof(double));
    arr   = calloc(c * sizeof(double *), sizeof(double));
    for(y=0;y<c;y++)
    {
        arr[y] = (double *)space + (y*r);   
    }
    return arr;
}

double *** Create3D(int p, int c, int r) 
{
    double *space;
    double ***arr;
    int    x,y;

    space = calloc (p*c*r*sizeof(double),sizeof(double));
    arr = calloc(p * sizeof(double **), sizeof(double));
    for(x = 0; x < p; x++)
    {
        arr[x] = calloc(c * sizeof(double *),sizeof(double));
        for(y = 0; y < c; y++)
        {
            arr[x][y] = ((double *)space + (x*(c*r) + y*r));
        }
    }
    return arr;
}

double **** Create4D(int hR, int p, int c, int r)     
{
    double *space;
    double ****arr;
    int    w,x,y;

    space = calloc(hR*p*c*r*sizeof(double), sizeof(double));
    arr = calloc(hR * sizeof(double ***), sizeof(double));
    for(w=0;w<hR;w++)
    {
        arr[w] = calloc(p * sizeof(double **), sizeof(double));
        for(x=0;x<p;x++)
        {
            arr[w][x] = calloc(c * sizeof(double *), sizeof(double));
            for(y=0;y<c;y++)
            {                                        
                arr[w][x][y] = ((double *)space + (w*(p*c*r) + x*(c*r) + y*r)); 
            }
        }
    }
    return arr;
}

double ***** Create5D(int hC, int hR, int p, int c, int r) 
{
    double *space; 
    double *****arr;
    int    v,w,x,y;

    space = calloc(hC*hR*p*c*r*sizeof(double),sizeof(double));
    arr = calloc(hC * sizeof(double ****),sizeof(double));
    for(v=0;v<hC;v++)
    {
        arr[v] = calloc(hR * sizeof(double ***),sizeof(double));
        for(w=0;w<hR;w++)
        {
            arr[v][w] = calloc(p * sizeof(double **),sizeof(double));
            for(x=0;x<p;x++)
            {
                arr[v][w][x] = calloc(c * sizeof(double *),sizeof(double));
                for(y=0;y<c;y++)
                {
                    arr[v][w][x][y] = ((double *)space + (v*(hR*p*c*r) + w*(p*c*r) + x*(c*r) + y*r));   
                }
            }
        }
    }
    return arr;
}

double ****** Create6D(int hP, int hC, int hR, int p, int c, int r)
{
    double *space;
    double ******arr;
    int    u,v,w,x,y;

    space = calloc(hP*hC*hR*p*c*r*sizeof(double),sizeof(double));
    arr = calloc(hP * sizeof(double *****),sizeof(double));
    for(u=0;u<hP;u++)
    {
        arr[u] = calloc(hC * sizeof(double ****),sizeof(double));
        for(v=0;v<hC;v++)
        {
            arr[u][v] = calloc(hR * sizeof(double ***),sizeof(double));
            for(w=0;w<hR;w++)
            {
                arr[u][v][w] = calloc(p * sizeof(double **),sizeof(double));
                for(x=0;x<p;x++)
                {
                    arr[u][v][w][x] = calloc(c * sizeof(double *),sizeof(double));
                    for(y=0;y<c;y++)
                    {
                        arr[u][v][w][x][y] = ((double *)space + (u*(hC*hR*p*c*r) + v*(hR*p*c*r) + w*(p*c*r) + x*(c*r) + y*r));  
                    }
                }
            }
        }
    }
    return arr;
}
0 голосов
/ 24 января 2012

Ваш доступ к brr[j][k][m] незаконен. обратите внимание, что brr является указателем на CCOUNT массивов short[ACOUNT][BCOUNT], поэтому при доступе к нему первый индекс должен быть меньше CCOUNT.

(компилятор умножает первый индекс на ACOUNT*BCOUNT, а второй индекс на BCOUNT)

просто измените границу циклов или измените доступ на brr[m][j][k].

...