0

さまざまな理由から、多次元配列をメモリの連続したチャンクに割り当てたいと思います。手動で割り当てることでこれを行うことができます。例:

t.versions=(char***)malloc(sizeof(char**)*4);
t.versions[0]=(char**)malloc(sizeof(char*)*t.size*4);
t.versions[0][0]=(char*)calloc(t.size*t.size*4,sizeof(char));
for (i=1; i<t.size*4; ++i) 
    t.versions[0][i]=t.versions[0][i-1]+t.size;
for (i=1; i<4; ++i) 
    t.versions[i]=t.versions[i-1]+t.size;

他の利点の中でも、このソリューションは割り当てられたメモリの解放を簡素化します。

void contiguous_array_free(void** ptr, int depth)
{
    int *ptr_d;
    ptr_d=(int*)*ptr;
    if (depth>1)
        contiguous_array_free((void**)ptr_d, depth-1);
    free(ptr);
}
//(elsewhere in the code)
contiguous_array_free((void**)(*tile).versions, 3);

さて、これらの配列の割り当てに小さな問題があります-上記のアプローチは機能しますが、理想的には、単一の関数呼び出しでこれらの配列を割り当てることができる一般的なソリューションが必要です。

ただし、その目標を達成しようとすると、配列の内容が使用されるたびにプログラムがクラッシュします。

//dimension points to a 1-dimensional array of integers
//specifying the size in each array dimension
void* contiguous_array_alloc(int* dimension, int depth, int size)
{
    int i;
    char** ptr;
    if (depth==1)
    {
        ptr=(char**)malloc(*dimension*size);
        return ptr;
    }
    ptr=(char**)malloc(*dimension*sizeof(char*));
    *(dimension+1)*=*dimension;
    ptr[0]=(char*)contiguous_array_alloc(dimension+1, depth-1, size);
    *(dimension+1)/=(*dimension);
    for (i=1; i<*dimension; ++i)
        ptr[i]=ptr[i-1]+(*(dimension+1)*size);
    return (void*)ptr;
}

//(later in the code) (
int dimension[3];
dimension[0]=4;
dimension[1]=t.size;
dimension[2]=t.size;
t.versions=(char***)contiguous_array_alloc(&dimension[0], 3, sizeof(char));

コードにいくつかのデバッグメッセージを追加すると、要素が正しく割り当てられていることが示されているようです。

サイズ1の要素の[4][9][9]配列を割り当てます。malloc()は、4つのポインターに対して16バイトの配列を作成します。003E29E8のレベル2にポインタ配列を割り当てました。

サイズ1の要素の[36][9]配列を割り当てます。malloc()は、36個のポインターに対して144バイトの配列を作成します。003E5728でレベル1にポインタ配列を割り当てました。

サイズ1の要素の[324]配列を割り当てます。

003E57C0の324バイトのデータ配列。003E57C0でのポイントデータ。すべてのポインタを9ずつ増やします。割り当てられた配列を返します。

003E5728で指摘されたデータ。すべてのポインタを9ずつ増やします。割り当てられた配列を返します。

003E29E8に割り当てられた連続アレイ。

この動作の原因は何ですか?コードを数回チェックしましたが、何を間違えたのかわかりません。

4

2 に答える 2

1

ptr[i]=ptr[i-1]+(*(dimension+1)*size);このようなポインタ操作の使い方は意味がないので、何かおかしいと思います。4次元配列のテストに合格したコードを以下のように変更しました。

//dimension points to a 1-dimensional array of integers
//specifying the size in each array dimension
void* contiguous_array_alloc(int* dimension, int depth, int size) {
  int i;
  if (depth==2) {
    char ** ptr=(char **)malloc(*dimension * sizeof(void*));
    ptr[0]=(char *)malloc(*dimension * dimension[1] * size);
    for (i=1; i<*dimension; ++i) {
      ptr[i]=ptr[i-1]+(*(dimension+1) * size);
    }
    return (void*)ptr;
  } else {
    void ***ptr=(void***)malloc(*dimension * sizeof(void*));
    *(dimension+1)*=(*dimension);
    ptr[0]=contiguous_array_alloc(dimension+1, depth-1, size);
    *(dimension+1)/=(*dimension);
    for (i=1; i<*dimension; ++i) {
      ptr[i]=ptr[i-1]+(*(dimension+1));
    }
    return (void*)ptr;
  }
}
于 2013-02-27T18:04:28.407 に答える
0

abcdの配列に必要なのintは次のとおりです。

int (*p)[b][c][d] = calloc(a, sizeof *p);
于 2013-02-27T18:12:01.667 に答える