一篇介绍C语言中二级指针和二维数组的文章

我们知道C语言中指针也就是内存地址,指针变量是用来存放内存地址的变量。那么二级指针就是存放的指针的内存地址。int **arr 可以理解为一个二维数组的动态表示。它通常用于创建动态分配的二维数组,允许在运行时根据需要分配和管理内存。以下用一个例子和三个疑问来剖析二级指针和二维数组。

示例

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main() {
    int rows = 3, cols = 4;
    // Step 1: 分配行指针数组
    int **arr = (int **)malloc(rows * sizeof(int *));
    
    // Step 2: 为每一行分配内存
    for (int i = 0; i < rows; i++) {
        arr[i] = (int *)malloc(cols * sizeof(int));
    }
    // 填充数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            arr[i][j] = i * cols + j + 1; // 填充示例数据
        }
    }
    // 打印数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    // 释放内存
    for (int i = 0; i < rows; i++) {
        free(arr[i]); // 释放每一行的内存
    }
    free(arr); // 释放行指针数组
    return 0;
}

一、搞懂:真正的二维数组 vs 二级指针

真正的二维数组(栈上),它本质是:一维数组套一维数组

复制代码
int arr[3][4];

内存是一整块连续的

1\]\[2\]\[3\]\[4\]\[5\]\[6\]\[7\]\[8\]\[9\]\[10\]\[11\]\[12

用 malloc + int** 写的,内存不是连续的,结构是这样:

arr → [ 指针0 ] → [1][2][3][4]

指针1 \] → \[5\]\[6\]\[7\]\[8

指针2 \] → \[9\]\[10\]\[11\]\[12

  • arr 是一个指针,指向3 个指针
  • 这 3 个指针,每个又指向4 个 int
  • 所以可以用 arr[i][j]

二、为啥arr[i][j] == *(*(arr + i) + j)

在 C 语言中,数组下标运算 a[b] 被定义为 *(a + b)

在表达式中,数组名通常会退化为指向首元素的指针,因此 a[0] == *a 成立。

但需要注意:数组名本身不是指针,且该规则成立的前提是指针运算合法。

通过一步步运算我们可以得到arr[i][j] == *(*(arr+i)+j)

(arr[i])[j] --> *(arr[i] +j) --> *(*(arr+i)+j)

含义:

  • arr+i → 找到第 i 行指针
  • *(arr+i) → 拿到第 i 行地址
  • *(arr+i)+j → 第 i 行第 j 列元素地址
  • *(*(arr+i)+j) → 取出元素

三、为啥free先free每行再free掉arr

现在的结构是:

arr → 存了3个指针

指针0 → 一行数据

指针1 → 一行数据

指针2 → 一行数据

所以释放顺序必须是:

  1. 先把3 行数据分别 free 掉
  2. 再 free 掉 arr 自己

如果先 free (arr),那三行数据的地址就丢了,变成内存泄漏

相关推荐
-Marks-2 小时前
【C++编程】STL简介 --- (是什么 | 版本发展历程 | 六大组件 | 重要性缺陷以及如何学习)
开发语言·c++·学习·stl·stl版本
weixin_413920612 小时前
LVGL仪表显示项目
c语言
HealthScience2 小时前
【Bib 2026】基因最新综述(有什么任务、benchmark、代表性模型)
android·开发语言·kotlin
wjs20242 小时前
CSS 网格元素
开发语言
Java小白笔记3 小时前
OpenClaw 实战方法论
java·开发语言·人工智能·ai·全文检索·ai编程·ai写作
CoderCodingNo3 小时前
【信奥业余科普】C++ 的奇妙之旅 | 12:程序的交互与加工——数据的输入与算术运算
开发语言·c++
S1998_1997111609•X4 小时前
MacOS/ˉsh(so.))os.apkair/AI
开发语言·网络·人工智能
SimpleLearingAI4 小时前
C++虚函数详解
开发语言·c++