C语言指针专题四 -- 多级指针

目录

[1. 多级指针的核心原理](#1. 多级指针的核心原理)

[1. 多级指针的定义](#1. 多级指针的定义)

[2. 内存结构示意图](#2. 内存结构示意图)

[3. 多级指针的用途](#3. 多级指针的用途)

[2. 编程实例](#2. 编程实例)

实例1:二级指针操作(修改一级指针的值)

实例2:动态二维数组(二级指针)

实例3:三级指针操作(修改二级指针的值)

[3. 多级指针的常见陷阱](#3. 多级指针的常见陷阱)

[4. 总结](#4. 总结)


1. 多级指针的核心原理

多级指针 (如二级指针、三级指针)本质是 指向指针的指针,用于间接访问或修改其他指针的值。通过多级指针可以构建复杂的内存结构(如动态多维数组、链表中的指针传递等)。

1. 多级指针的定义

  • 二级指针:存储一级指针的地址。
cpp 复制代码
int a = 10;
int *p = &a;     // 一级指针,指向int变量
int **pp = &p;   // 二级指针,指向int*指针
  • 三级指针:存储二级指针的地址。
cpp 复制代码
int ***ppp = &pp;  // 三级指针,指向int**指针

2. 内存结构示意图

cpp 复制代码
栈内存布局:
+------+       +------+       +------+
| ppp  | ----> | pp   | ----> | p    | ----> a (值=10)
+------+       +------+       +------+
地址:0x1000    地址:0x2000    地址:0x3000    地址:0x4000
  • 定义另一个指针变量pps,并且把指针数组的首地址赋予指针pps。char *ps[5]={......}; char ** pps = ps; 如图所示

3. 多级指针的用途

  • 动态创建多维数组:通过二级指针管理动态二维数组。

  • 函数内修改外部指针:通过传递指针的指针,修改原始指针的值。

  • 复杂数据结构:如链表、树结构中管理节点指针的指针。

2. 编程实例

实例1:二级指针操作(修改一级指针的值)

cpp 复制代码
#include <stdio.h>

// 函数:修改外部指针的指向
void changePointer(int **pp) {
    int b = 20;
    *pp = &b;  // 通过二级指针修改一级指针的指向
    // 注意:此处b是栈变量,函数返回后其内存可能被覆盖!
}

int main() {
    int a = 10;
    int *p = &a;
    printf("Before: *p = %d\n", *p); // 输出10

    changePointer(&p);  // 传递指针的地址
    printf("After: *p = %d\n", *p);  // 输出20(实际存在风险,b已失效)
    return 0;
}

输出(实际可能因编译器优化不同):

cpp 复制代码
Before: *p = 10
After: *p = 20

警告 :此示例中,changePointer函数内修改p指向栈变量b,函数返回后b的内存可能被回收,导致p成为野指针。正确做法应动态分配内存。

实例2:动态二维数组(二级指针)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows = 3, cols = 4;
    int **matrix;  // 二级指针

    // 动态分配行指针数组
    matrix = (int**)malloc(rows * sizeof(int*));
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int*)malloc(cols * sizeof(int));  // 分配每行内存
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j;  // 初始化数据
        }
    }

    // 打印二维数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%2d ", matrix[i][j]);
        }
        printf("\n");
    }

    // 释放内存
    for (int i = 0; i < rows; i++) free(matrix[i]);
    free(matrix);
    return 0;
}

输出

cpp 复制代码
 0  1  2  3 
 4  5  6  7 
 8  9 10 11 

内存示意图

cpp 复制代码
二级指针matrix(堆内存)     各行数据(堆内存)
+--------+                +-----+-----+-----+-----+
| 0x1000 | ------> 行0 -->| 0   | 1   | 2   | 3   |
+--------+                +-----+-----+-----+-----+
| 0x1008 | ------> 行1 -->| 4   | 5   | 6   | 7   |
+--------+                +-----+-----+-----+-----+
| 0x1010 | ------> 行2 -->| 8   | 9   | 10  | 11  |
+--------+                +-----+-----+-----+-----+

实例3:三级指针操作(修改二级指针的值)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

void createMatrix(int ***ppp, int rows, int cols) {
    *ppp = (int**)malloc(rows * sizeof(int*));  // 分配行指针数组
    for (int i = 0; i < rows; i++) {
        (*ppp)[i] = (int*)malloc(cols * sizeof(int));  // 分配每行内存
        for (int j = 0; j < cols; j++) {
            (*ppp)[i][j] = i + j;  // 初始化数据
        }
    }
}

int main() {
    int **matrix = NULL;  // 二级指针初始化为空
    int rows = 2, cols = 3;

    // 通过三级指针传递,动态创建二维数组
    createMatrix(&matrix, rows, cols);

    // 打印数据
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%2d ", matrix[i][j]);
        }
        printf("\n");
    }

    // 释放内存
    for (int i = 0; i < rows; i++) free(matrix[i]);
    free(matrix);
    return 0;
}

输出

cpp 复制代码
 0  1  2 
 1  2  3 

3. 多级指针的常见陷阱

1. 野指针风险

cpp 复制代码
int **pp;
*pp = (int*)malloc(sizeof(int));  // 错误!pp未初始化,指向随机地址。

防御:确保多级指针指向合法内存后再操作。

2. 内存泄漏

cpp 复制代码
int **matrix = malloc(3 * sizeof(int*));
// 忘记释放matrix和每行的内存!

防御:逐层释放内存,顺序为先释放子内存,再释放父指针。

3. 越级解引用

cpp 复制代码
int a = 10;
int **pp = &a;  // 错误!pp应为int**类型,但&a是int*类型。

防御:严格匹配指针层级和数据类型。

4. 总结

核心规则

  • 层级匹配n级指针需指向(n-1)级指针的地址。

  • 内存管理:动态分配的多级指针必须逐层释放。

  • 类型安全:解引用时需确保层级和数据类型一致,避免未定义行为。

相关推荐
zhangzhangkeji2 小时前
c++ 定点 new 及其汇编解释
开发语言·c++
Oracle_6663 小时前
C基础算法与实现
c语言·算法
Pakho love3 小时前
Linux:文件与fd(被打开的文件)
android·linux·c语言·c++
硬件学长森哥3 小时前
音视频多媒体编解码器基础-codec
驱动开发·嵌入式硬件·音视频
我命由我123453 小时前
游戏引擎 Unity - Unity 下载与安装
c语言·开发语言·c++·后端·unity·c#·游戏引擎
h^hh4 小时前
向下调整算法(详解)c++
数据结构·c++·算法
我命由我123454 小时前
游戏引擎 Unity - Unity 启动(下载 Unity Editor、生成 Unity Personal Edition 许可证)
c语言·c++·后端·unity·c#·游戏引擎·ue4
Allen Bright4 小时前
Java动态代理:原理与实现
java·开发语言
海绵波波1074 小时前
350.两个数组的交集 ②
数据结构·算法·leetcode