使用malloc分配不同行长的多维数组

使用malloc分配不同行长的多维数组,c,arrays,malloc,C,Arrays,Malloc,我有以下C代码: int *a; size_t size = 2000*sizeof(int); a = (int *) malloc(size); 这很好用。但如果我有以下几点: char **b = malloc(2000*sizeof *b); 其中b的每个元素具有不同的长度 怎么可能对b执行与我对a相同的操作;i、 e.以下代码是否正确 char *c; size_t size = 2000*sizeof(char *); c = (char *) malloc(size); 如果

我有以下
C
代码:

int *a;
size_t size = 2000*sizeof(int);
a = (int *) malloc(size);
这很好用。但如果我有以下几点:

char **b = malloc(2000*sizeof *b);
其中
b
的每个元素具有不同的长度

怎么可能对
b
执行与我对
a
相同的操作;i、 e.以下代码是否正确

char *c;
size_t size = 2000*sizeof(char *);
c = (char *) malloc(size);

如果b中的每个元素都有不同的长度,则需要执行以下操作:

int totalLength = 0;
for_every_element_in_b {
    totalLength += length_of_this_b_in_bytes;
}
return (char **)malloc(totalLength);

首先,您需要分配一组指针,如
char**c=malloc(N*sizeof(char*))
,然后为每一行分配一个对
malloc
的单独调用,可能在循环中:


/* N is the number of rows  */
/* note: c is char** */
if (( c = malloc( N*sizeof( char* ))) == NULL )
{ /* error */ }

for ( i = 0; i < N; i++ )
{
  /* x_i here is the size of given row, no need to
   * multiply by sizeof( char ), it's always 1
   */
  if (( c[i] = malloc( x_i )) == NULL )
  { /* error */ }

  /* probably init the row here */
}

/* access matrix elements: c[i] give you a pointer
 * to the row array, c[i][j] indexes an element
 */
c[i][j] = 'a';

/*N是行数*/
/*注:c为字符***/
if((c=malloc(N*sizeof(char*))==NULL)
{/*错误*/}
对于(i=0;i

如果你知道元素的总数(例如,
N*M
),你可以在一次分配中做到这一点。

我认为两步方法是最好的,因为c 2-d数组就是数组和数组的数组。第一步是分配一个数组,然后在循环过程中为每个列分配数组。提供了很好的细节。

动态分配T型NxM数组的典型形式是

T **a = malloc(sizeof *a * N);
if (a)
{
  for (i = 0; i < N; i++)
  {
    a[i] = malloc(sizeof *a[i] * M);
  }
}
T**a=malloc(sizeof*a*N);
如果(a)
{
对于(i=0;i
如果数组的每个元素具有不同的长度,则将M替换为该元素的适当长度;比如说

T **a = malloc(sizeof *a * N);
if (a)
{
  for (i = 0; i < N; i++)
  {
    a[i] = malloc(sizeof *a[i] * length_for_this_element);
  }
}
T**a=malloc(sizeof*a*N);
如果(a)
{
对于(i=0;i
另一种方法是分配一个连续的内存块,包括用于指向行的指针的头块,以及用于在行中存储实际数据的体块。然后,只需在每行的基础上将主体中的内存地址分配给头中的指针,即可标记内存。情况如下:

int** 2dAlloc(int rows, int* columns) {    
    int header = rows * sizeof(int*);

    int body = 0;
    for(int i=0; i<rows; body+=columnSizes[i++]) {  
    }
    body*=sizeof(int);

    int** rowptr = (int**)malloc(header + body);

    int* buf  = (int*)(rowptr + rows);
    rowptr[0] = buf;
    int k;
    for(k = 1; k < rows; ++k) {
        rowptr[k] = rowptr[k-1] + columns[k-1];
    }
    return rowptr;
}

int main() {
    // specifying column amount on per-row basis
    int columns[] = {1,2,3};
    int rows = sizeof(columns)/sizeof(int);
    int** matrix = 2dAlloc(rows, &columns);

    // using allocated array
    for(int i = 0; i<rows; ++i) {
        for(int j = 0; j<columns[i]; ++j) {
            cout<<matrix[i][j]<<", ";
        }   
            cout<<endl;
    }

    // now it is time to get rid of allocated 
    // memory in only one call to "free"
    free matrix;
}
int**2dAlloc(int行,int*列){
int header=行*sizeof(int*);
int body=0;

对于(int i=0;i而言,
chara[10][20]
的等效内存分配如下所示

char **a;

a=(char **) malloc(10*sizeof(char *));

for(i=0;i<10;i++)
    a[i]=(char *) malloc(20*sizeof(char));
char**a;
a=(char**)malloc(10*sizeof(char*);

对于(i=0;imalloc不在特定边界上分配,因此必须假设它在字节边界上分配


如果将返回的指针转换为任何其他类型,则无法使用该指针,因为访问该指针可能会导致CPU内存访问冲突,应用程序将立即关闭。

2-D数组动态内存分配

int **a,i;

// for any number of rows & columns this will work
a = (int **)malloc(rows*sizeof(int *));
for(i=0;i<rows;i++)
    *(a+i) = (int *)malloc(cols*sizeof(int));
int**a,i;
//对于任意数量的行和列,这将起作用
a=(int**)malloc(rows*sizeof(int*);

对于(i=0;ii)如果在单个操作中分配NM字节,则手动填充所有c[i]:c[i]=p+Mi;这取决于c的类型-如果是char**,则是,如果是char*,则索引更改:元素[i][j]~c[i*M+j]@Nikolai N Fetissov,代码中有很多malloc,怎么能全部释放?通过使用for循环?@e19293001是的,每个
malloc
都有一个
free
。你必须循环通过
char*
变量释放它们,然后释放
char**
。我在一本书中看到了同样的情况,它说“…内存不保证是连续的。"?它不为char*指针的一维数组分配内存。需要注意的是:此解决方案通常在缓存一致性方面表现更好,因为与其他每次分配一行的方法不同,单个行保证是连续的,并且可能导致矩阵的组成部分分散在一个高度碎片化的堆中。不幸的是,这也有一个副作用,即不能保证非指针大小类型的对齐。例如:具有32位指针和奇数行的64位double的系统将在未对齐的边界上为
double
启动第一列double行。这一点非常重要ted,因为它很容易由于数据对齐不当而导致总线错误。一般解决方案应确保数据行从8字节边界开始,在将行指针分配给主指针段时产生额外的分配空间并进行相应调整。@DmitryAleks:您在哪里声明
columnSizes[]
?如果我有我将拥有的int的总数,但不是每个数组中有多少个int,我应该如何进行?回答非常清楚,谢谢!您还可以添加一个描述,说明如何正确地
释放
分配的内存吗?@Kagaratsch:一般来说,以与您分配的相反的顺序释放-也就是说,释放每个int
a[i]
先释放
a