将多维C ++数组作为一个连续块(在堆上)访问是否有效

时间:2013-11-08 15:34:29

标签: c++ arrays

此处的相关主题:Does C99 guarantee that arrays are contiguous?

显然answer()在下面无效,但可以重写为使用char *或强制转换为int [nElements](可能)。我承认我不理解标准引用,以及为什么如果正确对齐,则无法通过int *访问连续的int块。

首先是以下代码块在大多数C ++平台上有效吗?

void answer(int *pData, size_t nElements)
{
    for( size_t i=0; i<nElements; ++i )
        pData[i] = 42;
}

void random_code()
{
    int arr1[1][2][3][4];               // local allocation
    answer(arr1, sizeof(arr1) / sizeof(int));
    int arr2[20][15];
    answer(arr2, sizeof(arr2) / sizeof(int));
}

第二个answer()对所有分配类型(全局,本地,堆(希望是正确的!))仍然有效吗?

int g_arr[20][15]; // global
void foo() {
    int (*pData)[10] = new int[50][10];  // heap allocation, at least partially
    answer(&pData[0][0], 50*10);
    // not even sure if delete[] will free pData correctly, but...
}

3 个答案:

答案 0 :(得分:1)

answer()中的代码很好。 random_code()中的代码滥用answer()(或未调用问题中显示的answer()的重载)。它应该是:

void random_code()
{
    int arr1[1][2][3][4];
    answer(&arr1[0][0][0][0], sizeof(arr1) / sizeof(int));
    int arr2[20][15];
    answer(&arr2[0][0], sizeof(arr2) / sizeof(int));
}

answer()中的代码需要int *;您传递的是int (*)[2][3][4]int (*)[15],两者都不是int *

这对于分配单个连续数据块的其他分配机制仍然有效,例如显示的那些。

答案 1 :(得分:1)

是的,大多数平台确实会打包N维数组的元素,使得指向第一个元素的指针上的线性寻址将找到所有元素。

实际上很难(例如,我无法弄清楚)提出符合标准的实现,执行此操作,因为数组数组必须包含所述数组,并且数组数组的大小是每个子数组的大小乘以数组数组的数量。似乎没有房间因为它没有工作。甚至每个元素的排序似乎也很明确。

尽管如此,我所知道的标准中没有任何子句允许您实际将指向多维数组的第一个元素的指针重新解释为指向产品数组的指针。许多条款都讨论了如何只访问数组的元素,或者一个接一个的结束。

答案 2 :(得分:0)

正如之前的人所说,代码中存在类型错误。您正在尝试为int 形式参数使用int()[X]类型实际参数。因此,为了使您的代码有效,您应该使用类型转换。

C ++ / C对数据类型使用相同的内存布局,而不依赖于用于分配对象的内存部分,以便相同的代码可用于它们所在的值。因此,对于第二个问题的答案是,如果您的代码正在处理堆栈分配的值,那么它也将使用堆分配的值。