1. 指针与二维数组:那些年踩过的内存坑
十年前在培训班第一次听到"二维数组就是指针的指针"时,我天真地以为找到了捷径,直到程序崩溃后才明白这句话有多危险。二维数组int arr[3][4]在内存中是连续的12个int空间,而int** ptr则是完全不同的物种——它首先指向一个指针数组,每个指针再指向独立的内存块。
实测一个典型误区:尝试用二级指针接收二维数组参数。当我写下void func(int** mat)然后传入int arr[3][4]时,编译器竟然没报错!但运行时访问mat[1][2]直接段错误。后来用gdb查看内存布局才恍然大悟:
c复制// 错误示例
void print_matrix(int **mat, int rows, int cols) {
for(int i=0; i<rows; i++) {
for(int j=0; j<cols; j++) {
printf("%d ", mat[i][j]); // 这里会崩溃!
}
printf("\n");
}
}
int main() {
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
print_matrix((int**)arr, 3, 4); // 危险的强制转换
}
关键理解:二维数组名arr的类型是int(*)[4](数组指针),不是int**。当看到"数组退化为指针"时,退化的是第一维,第二维及更高维的尺寸信息必须保留。
2. 多级指针的俄罗斯套娃模型
三级指针int***在图形处理库的API设计中很常见,比如需要动态创建三维纹理时。理解它的秘诀是画"指针链"图:
code复制level3 → level2 → level1 → 实际数据
一个实用的内存分配模式:
c复制int*** create_3d_array(int x, int y, int z) {
int ***arr = malloc(x * sizeof(int**));
for(int i=0; i<x; i++) {
arr[i] = malloc(y *
