尝试在C中动态分配多维数组会导致崩溃

时间:2013-02-27 15:09:24

标签: c arrays multidimensional-array dynamic-allocation contiguous

由于种种原因,我想在连续的内存块中分配多维数组。我可以通过手动分配它们来实现这一点,例如:

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));

在代码中添加一些调试消息似乎表明元素已正确分配:

  

分配[4] [9] [9] 1号元素的数组;   malloc()用于4个指针的16字节数组;   在003E29E8处将指针数组分配到级别2;

     
    

分配[36] [9] 1号元素的数组;     malloc()用于36个指针的144字节数组;     在003E5728处将指针数组分配到级别1;

         
      

分配[324]大小为1的元素数组;

    
         <00> 003E57C0处的324字节数据阵列;     指向数据003E57C0;     将每个指针增加9;     返回已分配的数组;

  
     

003E5728的指向数据;   将每个指针增加9;   返回已分配的数组;

     

在003E29E8分配连续数组;

导致此行为的原因是什么?我已经多次检查过代码,不知道我做错了什么。

2 个答案:

答案 0 :(得分: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;
  }
}

答案 1 :(得分:0)

a b c d int数组所需的全部内容是:

int (*p)[b][c][d] = calloc(a, sizeof *p);