C++ 中的 2D 动态分配使用具有空间局部性的 New

2D Dynamic Allocation in C++ Using New with Spatial Locality

很抱歉问了一个基本问题,但我真的找不到合适的答案。我继承了一段 C++ 代码,其中一部分具有二维分配函数 Allocate2D,形式为:

float** Allocate2D(long long sizeX, long long sizeY)
{
    float** p = new float*[sizeY];
    p[0] = new float[sizeX*sizeY];

    for (long long z = 0; z < sizeY; z++) {
        p[z] = p[0] + z * sizeX;
    }
    return ptr;
}

int main(){
    long long nX = ... ; 
    long long nY = ... ; 
    short** A = (short **)Allocate2D(nX, nY);
    // do stuff with A ...
}

我有两个问题:

1- Allocate2D 是否正在创建大小为 sizeX x sizeY 的二维数组?

2- 当为 float** 定义了 Allocate2d 时,这种 common/legal/good 分配二维 short 数组(例如 A 的做法吗?

  1. 是的。它确实取决于“二维数组”的确切含义。创建用于存储按二维索引的数据的数据结构的方法不止一种。可以用二维解引用 A,如 A[y][x],它会按预期工作。此外,A[0] 中将有一个指针指向 sizeX x sizeY 浮点数的连续数组,其中 X 维度变化最快。这是 float B[sizeY][sizeX] 也会得到的内存布局。但是,AB 的类型(忽略 float 与 short)并不相同。 A 是指向指针数组的指针,而 B 衰减为指向浮点数的指针。

  2. 没有。将指针强制转换为指向不同类型是不合法的。它打破了指针别名规则。此外,由于 sizeof(float) 几乎肯定不等于 sizeof(short),数组的大小将是错误的,即它将是 nX*2 × nY。但是,由于 float* 永远不会被解除引用为 float,我们可以清楚地看到浮点指针的生命周期非常有限,因此实际上不会有问题。

所以这会起作用,除了数组是它应该的两倍大。但是将浮点指针转换为短指针在严格意义上是不合法的,而且很丑陋。编写一个使类型正确的函数模板会更好,也很容易。