c ++中二维数组的动态内存分配

时间:2016-08-25 04:40:35

标签: c++ arrays multidimensional-array

我正在阅读一本C ++书,作者提到了

  

可以使用单个新语句创建二维数组。

     

array_ptr = new int [3] [2];

我尝试用一​​个新的运算符编写一个代码段来创建一个二维数组,并且它抛出了编译错误。

在这种情况下,我觉得作者错了。

功能

  • 在C ++中 - >允许使用new int [10]

BUT

  • new int [10] [20]是不允许的

如果我的上述结论是正确的,我会很感激。

2 个答案:

答案 0 :(得分:2)

这是允许的,但你可能得到左侧的类型错了。使用:

int (*ptr)[2] = new int[3][2];

auto *ptr = new int[3][2];

编译时必须知道除最里面以外的所有尺寸。如果在编译时不知道这两个维度,那么您就不能使用这种语法。相反,您将使用一维数组并计算偏移量来模拟二维数组。

NB。在大多数情况下,根本不使用new,使用管理自己内存的容器。

有关多维数组的更多信息,请参阅this question上的答案。

答案 1 :(得分:0)

该函数可以动态创建连续的多维数组。

void* ArrayND(size_t size_m, unsigned short numargs, ...);

参数:

size_m : 单个成员的字节大小。

numargs : 总维数。

...:行和列。

示例:

int ****arr = (int***)ArrayND(sizeof(int), 4, 3, 2, 5, 20);
arr[0][1][0][11] = 0;

函数代码:

static void* ArrayND(size_t size_m, unsigned short numargs, ...)
{
    va_list listPointer;
    va_start(listPointer, numargs);

    if (numargs < 1 || size_m < 1) return 0;

    size_t* args = (size_t*)listPointer;

    if (!args[0] || !args[numargs - 1]) ///Dimension == 0 case
    {
        va_end(listPointer);
        return 0;
    }

    if (numargs == 1)
    {
        void* array = (void*)malloc(size_m * args[0]);
        va_end(listPointer);
        return array;
    }

    size_t* PtrProdSum = (size_t*)malloc(((numargs - 1) * 2) * sizeof(size_t));
    size_t* PtrProd = &PtrProdSum[numargs - 1];

    if (!PtrProdSum) return 0;

    PtrProdSum[0] = args[0];
    PtrProd[0] = args[0];

    for (unsigned short j = 1; j < numargs - 1; j++)      ///Calculating the number of (*) pointers and double pointers (**)
    {
        if (args[j] < 1)    ///Dimension < 1 case
        {
            free(PtrProdSum);
            free(PtrProd);
            va_end(listPointer);
            return 0;
        }
        PtrProd[j] = PtrProd[j - 1] * args[j];
        PtrProdSum[j] = PtrProd[j] + PtrProdSum[j - 1];
    }

    size_t len = (sizeof(void*) * PtrProdSum[numargs - 2]) + (size_m * PtrProd[numargs - 2] * args[numargs - 1]);
    void** array = (void**)malloc(len);      ///assign a big block of memory

    if (!array) return 0;

    unsigned short j = 0;       ///j = number block of usable memory

    size_t PPprodSum, PprodSum = PtrProdSum[numargs - 2];
    size_t ColMemory = size_m * args[numargs - 1];
    char* ptr = (char*)(array + PprodSum);

    ///assigning array addresses
    if (numargs > 2)
    {
        unsigned short k = 1;       ///k = index of args to process the addresses
        PPprodSum = PtrProdSum[numargs - 3];
        size_t last_jump = args[0];

        for (size_t i = 0; i < PPprodSum; i++)      ///assigning (**) double pointers addresses
        {
            array[i] = (void**)array + (last_jump + i);
            //printf("array[%d]  :  %d  to  %d   last_jump = %d   PtrProdSum = %d   args = %d\n", i, &array[i], array[i], last_jump, PtrProdSum[k], args[k]);

            if (i >= PtrProdSum[k - 1] && k < numargs - 2) k++;
            last_jump += args[k] - 1;
        }
    }
    else PPprodSum = 0;

    va_end(listPointer);
    free(PtrProdSum);

    for (size_t i = PPprodSum; i < PprodSum; i++)       ///assigning (*) pointers to members memory addresses
    {
        array[i] = ptr + ColMemory * j;
        //printf("array[%d] = %d    jump = %d    sum = %d\n", i, &array[i], ptr + (ColMemory * j), (ColMemory * j));

        j++;
    }

    return (void*)array;
}

待办事项: malloc() 失败时的错误处理。

来源:https://github.com/TheViper01/MyProjects