C++两种矩阵内存分配差异及寻址原理疑问
C++动态矩阵内存连续性与访问问题解答
先明确两种矩阵创建方式:
- 静态矩阵:
int matrix[rows][columns];,在栈(或全局存储区)一次性分配一块连续的rows * columns大小的内存,整体是连续的二维数组。 - 动态矩阵(指针数组方式):
int** matrix = new int*[rows]; for(int i = 0; i < rows; i++) matrix[i] = new int[columns];
这种方式是先创建一个存储指针的数组,再为每个指针单独申请一行的内存。
1. 为何动态矩阵行间内存不连续?
因为new操作是向堆内存发起独立的分配请求。第一次new int*[rows]是申请能存rows个指针的连续内存;之后循环里的每一次new int[columns]都是单独向堆申请一块能存columns个int的内存块。堆内存的分配是基于当前空闲内存块的情况,每次分配的块位置由内存管理器决定,没有机制保证这些独立申请的内存块会彼此相邻,所以行与行之间的内存自然不连续。
而静态矩阵是一次性申请整块内存,内存管理器直接分配一段连续的空间,所以整个矩阵的内存是连续的。
2. 若动态矩阵元素内存不连续,C++如何通过[i][j]正确遍历矩阵?
int** matrix本质是指针的指针:
matrix[i]等价于*(matrix + i),表示取指针数组中第i个元素,这个元素是一个指向int数组的指针,也就是第i行的首地址。matrix[i][j]等价于*(matrix[i] + j),是从第i行的首地址往后偏移j个int的位置,然后取值。
这里的关键是,每一行内部的内存是连续的(因为new int[columns]分配的是连续块),而matrix[i]已经准确指向了该行的首地址。不管行与行之间是否连续,只要matrix[i]是有效的行指针,就能正确定位到该行的第j个元素,和其他行的内存位置无关。
内容的提问来源于stack exchange,提问作者Ricardo Roel
相关产品推荐
相关产品推荐

