c++为什么不支持直接创建动态的多维数组?

C/C++为什么不支持直接创建动态的多维数组呢?
如果要需要一个二维数组int dpsize1, size1和size2都是在程序运行中确定的。采用

int[][] dp = new int[size1][size2];

的方式,会报错“expected unqualified-id before '[' token”。

对这类需求可以通过

int** dp = new int*[size1]
for (int i = 0; i < size1; i++) {
    dp[i] = new int[size2];
}

的方式来创建,但是这样得到的数组在创建是比较麻烦,内存空间也不一定是连续的。
为什么c/c++语言不支持直接采用new ints[s]的方式来创建多维数组呢?

阅读 7.1k
5 个回答

其实现在的C标准是兹磁的,你可以这样写

int *old_dp = malloc(sizeof(int) * size1 * size2);
int (*dp)[size2] = (int(*)[size2])(old_dp);
// 然后直接写dp[i][j]就可以啦,注意不要越界

c++的话确实是标准不兹磁,如果实在想追求效率的话只能写个函数包装一下了

标准规定了的。
可变长数组的只能是最外面那个维度是可变的,其它的得是固定的。
本来这就是一个比较低级的操作,分配一大块内存,还要求是连续的,由于数组本身是没有越界检查的,很容易写出相互覆盖的有问题的代码。而且不便于编译器优化。因为那样的话数组的每一维度的偏移都是要实时计算的,而多数CPU只能提供两级的间接寻址,所以要求里面的维度都是固定的,这样可以编译时就计算出来。

~~

为什么c/c++语言不支持直接采用new ints[s]的方式来创建多维数组呢?

因为标准没支持,所以不支持

动态的创建多维数组除了你上面写的那种还可以直接new int[size1 * size2],然后以偏移来访问,如果不要求连续,还有模板可以用vector<vector<int>> d2array

补充上面的回答:
C11是支持的,但是只能最外面的维度可以变。我觉得还是效率问题,越界检查损失效率。

#include <stdio.h>
#include <stdlib.h>
#define size1 2
#define size2 3

int main()
{
    int i = 0;
    int j = 0;
    int *old_dp = malloc(sizeof(int)*size1*size2);
    int(*dp)[size2] = (int(*)[size2])(old_dp);


    for (i = 0; i < size1; ++i)
        for (j = 0; j < size2; ++j)
            dp[i][j] = 9;

    for (i = 0; i < size1; ++i)
        for (j = 0; j < size2; ++j)
            if (j == size2 - 1)
                printf("%d\n", dp[i][j]);
            else
                printf("%d ", dp[i][j]);

    return 0;
}

因为array的内存分配是连续的,到底层要么是brk()使得program break向高地址移动,要么是mmap()向低地址移动,比如说一个二维数组array[n][m],第一维n如果+1的话,那么就得申请m * sizeof(object)的内存空间,有很大的可能brk()或者mmap()失败返回ENOMEM。你要自己实现动态数组也不是什么难事,做好边界检查和错误处理。想了解更多内存分配管理相关的东西,可以参考我的博文

推荐问题