C++ C+中的二维动态分配+;使用具有空间局部性的新方法
我很抱歉问了一个基本问题,但我真的找不到合适的答案。我继承了一个C++代码,其中的一部分有一个2D分配函数<代码> AlLoaDe2D2/代码>:C++ C+中的二维动态分配+;使用具有空间局部性的新方法,c++,new-operator,C++,New Operator,我很抱歉问了一个基本问题,但我真的找不到合适的答案。我继承了一个C++代码,其中的一部分有一个2D分配函数 AlLoaDe2D2/代码>: 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++) {
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 ...
}
float**Allocate2D(long-long-sizeX,long-long-sizeY)
{
浮动**p=新浮动*[sizeY];
p[0]=新浮点数[sizeX*sizeY];
用于(长z=0;z
关于这一点,我有两个问题:
1-是否Allocate2D
创建一个大小为sizeX
xsizeY
的二维数组
2-当为float**
定义Allocate2d
时,这种分配二维short
数组(如a
)的常见/合法/良好做法是什么
A
的引用,如A[y][x]
中所述,它将按预期工作。此外,a[0]
中还有一个指针,指向一个连续的sizeX sizeY float数组,其中x维度变化最快。这是使用float B[sizeY][sizeX]
也可以得到的内存布局。然而,A
和B
的类型(忽略浮动与短)并不相同A
是指向指针数组的指针,而B
则衰减为指向浮点的指针
sizeof(float)
几乎肯定不等于sizeof(short)
,因此数组的大小将是错误的,即它将是nX*2×nY
。然而,由于float*
从未被解引用为float
,我们可以清楚地看到,浮点指针的生命周期非常有限,因此实际上不会有问题
A
的引用,如A[y][x]
中所述,它将按预期工作。此外,a[0]
中还有一个指针,指向一个连续的sizeX sizeY float数组,其中x维度变化最快。这是使用float B[sizeY][sizeX]
也可以得到的内存布局。然而,A
和B
的类型(忽略浮动与短)并不相同A
是指向指针数组的指针,而B
则衰减为指向浮点的指针
sizeof(float)
几乎肯定不等于sizeof(short)
,因此数组的大小将是错误的,即它将是nX*2×nY
。然而,由于float*
从未被解引用为float
,我们可以清楚地看到,浮点指针的生命周期非常有限,因此实际上不会有问题
因此,这将起作用,而不是数组的大小是其应有大小的两倍。但是,将浮点指针转换为短指针并不是严格合法的,而且很难看。编写一个类型正确的函数模板会好得多,也很容易。值得理解的技术点是,没有2D数组这样的东西。您有一个指向浮点数的指针数组(因此为
**
),每个指针都指向自己的浮点数数组。这是一个“数组数组”。我之所以提出这一点,是因为将它放入一个类中是一次性的工作,内存是连续分配的。好吧,代码就是这样。正在分配一个指针数组和一个大的float
s数组(如果short
的公共大小为16位,则数据太多)。float
s数组被分成几行,每行分配给指针数组中的一个指针,然后可以像二维数组一样使用。这使数据保持良好的连续性,并且通常比单独对每一行进行new
ing(搜索词:空间局部性)提供了显著的性能优势。这比内存分散在所有位置的最坏情况要好,但此解决方案有一个冗余的指针数组和指针跟踪。它还需要手动管理这两个分配,这可能比看起来要复杂得多。我上面链接的包装器类只有一个数组,该数组由std::vector
管理,因此当您处理完它时,内存总是被放在一边(除非您特意不这样做),指针跟踪被一些非常简单的数学所取代。缺点是它看起来不像数组,你必须为它编制索引矩阵(x,y)
,而不是更熟悉的矩阵[x][y]
。值得理解的技术点是,没有2D数组这样的东西。您有一个指向浮点数的指针数组(因此为**
),每个指针都指向自己的浮点数数组。这是一个“数组数组”。我之所以提出这一点,是因为将它放入一个类中是一项一次性工作,内存是连续分配的