C++ 访问多维C++;数组作为一个连续块(在堆上)

C++ 访问多维C++;数组作为一个连续块(在堆上),c++,arrays,C++,Arrays,相关线程在此: 显然,answer()在下面无效,但可以重新写入以使用char*或强制转换为int[neelements](可能)。我承认我不理解标准引用,也不理解如果正确对齐,为什么不能通过int*访问int的连续块 首先,下面的代码块在大多数C++平台上有效吗? void answer(int *pData, size_t nElements) { for( size_t i=0; i<nElements; ++i ) pData[i] = 42; } voi

相关线程在此:

显然,
answer()
在下面无效,但可以重新写入以使用char*或强制转换为int[neelements](可能)。我承认我不理解标准引用,也不理解如果正确对齐,为什么不能通过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()
中的代码正常。
random\u 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*


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

是的,大多数平台确实会以这样的方式打包N维数组的元素,即指向第一个元素的指针上的线性寻址将找到所有元素

实际上,很难(如,我无法理解)提出一个不符合标准的实现,因为阵列阵列必须打包所述阵列,阵列阵列阵列的大小是每个子阵列的大小乘以阵列阵列的数量。似乎没有空间让它不工作。甚至每个元素的顺序似乎都定义得很好


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

正如前面的人所说,代码中存在类型错误。您试图使用int()[X]类型的实际参数作为int形式参数。因此,要使代码正常工作,应该使用类型转换


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

您正在谈论他的行:
answer(&pData[0][0],50*10)?所以我需要转换pData?我想我应该先运行这个,dern伪代码。它看起来也是这样的:
answer((int*)arr1,sizeof(arr1)/sizeof(int))“这对于其他分配机制仍然有效”-除了任何基于循环的数组分配以及对new、malloc等的多个调用。这些可能是锯齿状的,或者可能分布在内存中。是的,您也可以使用蛮力强制转换。我的回答中的“分配单个连续数据块”一词不包括“基于循环的数组分配,对new、malloc等的调用不止一次”。嗯,我唯一能想到的是关于“假设8字节边界”的事情,因为某种原因,每个数组“必须”在其中一个边界上对齐。但这样内存块就不会是sizeof(type)*mn。。。它实际上会更大。我想我会回到我的直觉:只要对单暗阵列做任何重要的事情。@ebyrob是的,阵列间填充是非法的。在不同维度上以奇怪的方式重新排列元素可能是非法的。我甚至想不出分段内存是如何妨碍我(这通常是我对这种疯狂的追求),因为数组的数组需要都在同一个段中。。。可能是一个指针内存模型,其中最大到某个大小的对象在内存中的位置是单向的,而较大的对象在内存中的位置是反向的,如果指向类型的大小足够大,则
指针+整数
反转加法-这种病理情况实际上可能是标准的合法情况?哇,是的,在一个架构中结合使用类固醇的大小endian可能会打破它!太棒了。@K-ballo dupe线程在哪里谈论堆分配?
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));
}