我想我们都同意,通过以一维方式解引用(可能是偏移的)指向其第一个元素的指针来访问真正的多维数组被认为是惯用的C,例如:
void clearBottomRightElement(int *array, int M, int N)
{
array[M*N-1] = 0; // Pretend the array is one-dimensional
}
int mtx[5][3];
...
clearBottomRightElement(&mtx[0][0], 5, 3);
Run Code Online (Sandbox Code Playgroud)
然而,我的语言律师需要说服这实际上是明确定义的C!特别是:
是否标准保证编译器不会把填充例如,在中间mtx[0][2]和mtx[1][0]?
通常,索引关闭数组的末尾(除了结尾之外)是未定义的(C99,6.5.6/8).所以以下内容显然是未定义的:
struct {
int row[3]; // The object in question is an int[3]
int other[10];
} foo;
int *p = &foo.row[7]; // ERROR: A crude attempt to get &foo.other[4];
Run Code Online (Sandbox Code Playgroud)
因此,根据相同的规则,人们会期望以下内容未定义:
int mtx[5][3];
int (*row)[3] = &mtx[0]; // The object in question is still an int[3]
int *p = &(*row)[7]; …Run Code Online (Sandbox Code Playgroud)沿着这条线的讨论可以在这个问题中找到,也可以在这里找到,但我的情况略有不同,因为我正在处理一个动态分配的内存.
还请注意,memset并不是很有double价值.
无论如何,我试图用来std::fill填充动态分配的2D数组 -
#include <iostream>
#include <algorithm>
using std::cout ; using std::endl ;
using std::fill ;
int main()
{
double **data ;
int row = 10, col = 10 ;
data = new double*[row] ;
for(int i = 0 ; i < col ; i++)
data[i] = new double[col];
// fill(&(data[0][0]),
// &(data[0][0]) + (row * col * sizeof(double)), 1); // approach 1
// fill(&(data[0][0]), &(data[0][0]) + (row * …Run Code Online (Sandbox Code Playgroud)