C语言中数组的动态分配

C语言中数组的动态分配,c,arrays,memory,dynamic-memory-allocation,allocation,C,Arrays,Memory,Dynamic Memory Allocation,Allocation,我并不真正理解C语言中的一些基本东西,比如动态分配数组数组。 我知道你可以做到: int **m; 为了声明一个二维数组(随后将使用某个*alloc函数进行分配)。也可以通过执行*(*(m+行)+列)来“轻松”访问它。但是我应该如何从该数组中为元素赋值呢?使用gcc,以下语句m[行][列]=12因分段错误而失败 任何物品/文件将不胜感激。:-) 使用malloc(3)分配第一个数组,并将malloc(3)创建的指针放入其中,应该与array[r][c]配合使用,因为它应该等价于*(*(arra

我并不真正理解C语言中的一些基本东西,比如动态分配数组数组。 我知道你可以做到:

int **m;
为了声明一个二维数组(随后将使用某个*alloc函数进行分配)。也可以通过执行
*(*(m+行)+列)
来“轻松”访问它。但是我应该如何从该数组中为元素赋值呢?使用gcc,以下语句
m[行][列]=12因分段错误而失败


任何物品/文件将不胜感激。:-)

使用
malloc(3)
分配第一个数组,并将
malloc(3)
创建的指针放入其中,应该与
array[r][c]
配合使用,因为它应该等价于
*(*(array+r)+c)
,这是c标准。

m[line][column]=12
语法没有问题(提供的
在范围内)

但是,您没有编写用于分配它的代码,因此很难判断它是对是错

m = (int**)malloc(nlines * sizeof(int*));

for(i = 0; i < nlines; i++)
  m[i] = (int*)malloc(ncolumns * sizeof(int));
m=(int**)malloc(nlines*sizeof(int*);
对于(i=0;i
一些旁注:

  • 这样,您可以为每一行分配不同的长度(例如三角形数组)
  • 在以后使用数组时,可以使用realloc()或free()单独的行
  • 在释放()整个数组时,必须释放()每一行

您的语法m[line][colummn]是正确的。但是为了在C中使用2D数组,您必须为其分配内存。例如,此代码将为给定行和列的表分配内存

int** AllocateArray(int line, int column) {
  int** pArray = (int**)malloc(line*sizeof(int*));
  for ( int i = 0; i < line; i++ ) {
    pArray[i] = (int*)malloc(column*sizeof(int));
  }
  return pArray;
}
int**allocaterRay(int行,int列){
int**pArray=(int**)malloc(line*sizeof(int*);
对于(int i=0;i

注意,为了简洁起见,我省略了malloc的错误检查。真正的解决方案应该包括它们。

它不是一个2d数组,而是一个数组数组,因此它需要多次分配。

尽管我同意其他答案,但在大多数情况下,一次分配整个数组会更好,因为malloc非常慢


int **
array_new(size_t rows, size_t cols)
{
    int **array2d, **end, **cur;
    int *array;

    cur = array2d = malloc(rows * sizeof(int *));
    if (!array2d)
        return NULL;

    array = malloc(rows * cols * sizeof(int));
    if (!array)
    {
        free(array2d);
        return NULL;
    }

    end = array2d + rows;
    while (cur != end)
    {
        *cur = array;
        array += cols;
        cur++;
    }

    return array2d;
}
要释放阵列,只需执行以下操作:
free(*数组);free(数组);


注意:此解决方案仅在您不想更改行的顺序时有效,因为您可能会丢失第一个元素的地址,稍后需要释放阵列。

哼哼。作为一个选项,旧式烟雾和镜像如何

#define ROWS  5
#define COLS 13
#define X(R, C) *(p + ((R) * ROWS) + (C))

int main(void)
{
    int *p = (int *) malloc (ROWS * COLS * sizeof(int));
    if (p != NULL)
    {
        size_t r;
        size_t c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLS; c++)
            {
                 X(r,c) = r * c;  /* put some silly value in that position */ 
            }
        }

        /* Then show the contents of the array */ 
        for (r = 0; r < ROWS; r++)
        {
            printf("%d ", r);   /* Show the row number */ 

            for (c = 0; c < COLS; c++)
            {
                 printf("%d", X(r,c));
            }

            printf("\n");
        }

        free(p);
    }
    else
    {
        /* issue some silly error message */ 
    }

    return 0;
}
#定义第5行
#定义COLS 13
#定义X(R,C)*(p+((R)*行)+(C))
内部主(空)
{
int*p=(int*)malloc(ROWS*COLS*sizeof(int));
如果(p!=NULL)
{
大小;
尺寸c;
对于(r=0;r
这里有一个修改版本,它只分配一个内存块,可以通过
void*
与通用值一起使用:

#include <stdlib.h>
#include <string.h>
#include <assert.h>

void ** array2d(size_t rows, size_t cols, size_t value_size)
{
    size_t index_size = sizeof(void *) * rows;
    size_t store_size = value_size * rows * cols;

    char * a = malloc(index_size + store_size);
    if(!a) return NULL;

    memset(a + index_size, 0, store_size);
    for(size_t i = 0; i < rows; ++i)
        ((void **)a)[i] = a + index_size + i * cols * value_size;

    return (void **)a;
}

int printf(const char *, ...);

int main()
{
    int ** a = (int **)array2d(5, 5, sizeof(int));
    assert(a);
    a[4][3] = 42;
    printf("%i\n", a[4][3]);
    free(a);
    return 0;
}
像这样使用它们:

int ** a = alloc_array2d(int, 5, 5);
init_array2d(a, int, 5, 5);
a[4][3] = 42;

@jpalecek:我分配内存的方式是:m=malloc(行*列*大小(int*));@hyperboreean:那将分配一个一维指针数组。你想要的是一个指针数组,每个指针指向另一个数组。你需要首先分配指针数组,然后为每个指向的数组分配内存。哇,两个可怜的无用编辑。@chakrit:铸造malloc通常被认为是不好的在C中进行操作,因为它不是必需的,并且可以掩盖错误。@Robert,原始答案为+1。不幸的是,这取决于编译器的实现。一些较旧的编译器具有非标准的malloc,需要强制转换。VisualStudio直到最近才采用这种方式(不记得确切的版本)铸造MALLC是C++中的好实践,因为如果LHS上的变量不是空指针,那么它是必需的。C中的错误做法是因为它消除的警告几乎总是需要正确处理的错误,并且删除警告只是处理症状。这可能是我的问题,我正受到SEG错误。这是一个错误。聪明的解决方案:)虽然如果我想立即分配它,我可能会求助于“array[I*cols+j]”寻址并放弃“array2d”数组。有几种方法可以在C中动态创建“多维数组”,它们之间有细微但重要的区别,请参阅以获取详细信息。另外,作为对其他人关于强制执行malloc的危险的警告:。这不是“数组数组数组”。
calloc
分配数组并将其归零
init_array2d
可能是多余的,除非有一个版本可以将每个单元格设置为一个非
(TYPE)0
int ** a = alloc_array2d(int, 5, 5);
init_array2d(a, int, 5, 5);
a[4][3] = 42;