嵌套循环方式分配4D数组内存占用远超连续缓冲区的原因咨询
嵌套循环方式分配4D数组内存占用远超连续缓冲区的原因咨询
嘿,这个问题我刚好踩过坑!咱们来好好拆解一下为啥嵌套循环分配的4D数组内存会比连续缓冲区大这么多~
首先,你用嵌套new的方式,本质上是在创建多层指针数组,而不是直接存储图像数据——每一层new都会额外分配一批指针,这些指针本身也要占用内存:
- 第一层:
new unsigned char*** [NumImages],这是一个存储unsigned char***类型指针的数组,每个指针在64位系统下占8字节,这部分开销是NumImages * 8字节。 - 第二层:每个图像对应的
new unsigned char** [ImageWidth],又是一批unsigned char**指针,总开销是NumImages * ImageWidth * 8字节。 - 第三层:每一行对应的
new unsigned char* [ImageHeight],再加上一批unsigned char*指针,总开销是NumImages * ImageWidth * ImageHeight * 8字节。 - 只有最后一层
new unsigned char[ColorChannels]才是真正存储RGB像素的地方,这部分大小是NumImages * ImageWidth * ImageHeight * ColorChannels字节。
而连续缓冲区呢?只需要一块连续的内存来存储所有像素数据,完全没有这些额外的指针开销!
除此之外,还有内存对齐的隐形开销:操作系统分配内存时,通常会按特定字节数(比如16字节)对齐,每次小粒度的new分配都会额外占用一点对齐空间,这些零碎的开销累加起来,也会让总内存占用进一步变大。
举个直观的例子:假设NumImages=100,ImageWidth=1000,ImageHeight=1000,ColorChannels=3:
- 连续缓冲区的内存占用是
100*1000*1000*3 = 300,000,000字节(约286MB)。 - 嵌套分配的话,光指针部分就占了
100*8 + 100*1000*8 + 100*1000*1000*8 = 800,800,800字节(约764MB),再加上像素数据的300MB,总内存直接破1GB,确实比连续缓冲区大了一个数量级!
另外还要提一句:这种嵌套分配不仅费内存,访问数据时的效率也更低——因为要多次解引用指针,CPU缓存的命中率会很差;而连续缓冲区的内存是连续排布的,不仅缓存效率高,也更适合你要的按Z方向(图像栈的列)检索像素的需求,因为同一列的像素在内存里是连续的,访问起来快很多。
备注:内容来源于stack exchange,提问作者user27269143
相关产品推荐
相关产品推荐

