裸指针使用教程(C/C++ 裸指针从入门到精通)

指针是 C、C++ 语言的核心精髓 ,而 裸指针(Raw Pointer) 就是最原始、最基础的普通指针,即直接使用 * 定义、无智能指针包装、无自动内存管理的原生指针。相比于 C++11 之后的 shared_ptr、unique_ptr 等智能指针,裸指针性能极致、开销几乎为零,但需要开发者手动管理内存、严格规避内存风险。

无论是底层开发、算法刷题、嵌入式编程、操作系统、框架源码阅读,裸指针都是必须掌握的基础能力。本文将从零讲解裸指针的概念、语法、运算、常见用法、经典场景以及高频避坑点,零基础也能快速上手。

一、什么是裸指针?

1. 核心定义

裸指针:泛指 C/C++ 原生的普通指针,直接存储变量的内存地址,没有任何封装、没有自动回收机制,完全由开发者手动控制内存的申请与释放。

常见裸指针形式:int*char*double*、自定义结构体指针等。

与智能指针的核心区别:

  • 裸指针:手动 new/delete,无引用计数,不自动释放,性能高,风险高

  • 智能指针:自动内存管理,安全性高,有少量性能开销

2. 指针与地址的通俗理解

  • 内存地址:电脑内存中每一块空间的唯一编号,类似房间门牌号

  • 指针变量:专门用来存放「门牌号(内存地址)」的变量

  • 解引用:通过门牌号,找到对应的房间并操作里面的数据

二、裸指针基础语法(定义与初始化)

1. 指针定义规则

语法格式:数据类型 * 指针变量名

复制代码

int* p; // 定义一个int类型裸指针 char* str; // char类型裸指针 double* dp; // double类型裸指针

注意:* 属于变量,不属于类型,int* pint *p语法完全等价。

2. 取地址与解引用(两大核心操作)

  • & 取地址符:获取变量的内存地址

  • * 解引用符:通过指针地址,访问对应内存中的数据

复制代码

#include <iostream> using namespace std; int main() { int a = 100; int* p = &a; // 指针p保存变量a的地址 cout << "a的地址:" << &a << endl; cout << "指针p存储的地址:" << p << endl; cout << "指针解引用的值:" << *p << endl; *p = 200; // 通过指针修改原变量的值 cout << "修改后a的值:" << a << endl; return 0; }

核心结论:指针修改解引用的值,会直接修改原变量,因为二者指向同一块内存空间。

3. 空指针初始化(规范写法)

未初始化的裸指针会指向随机脏内存,极易导致程序崩溃,定义指针必须初始化:

复制代码

// 规范1:C++11及以上,推荐 int* p = nullptr; // 规范2:C语言常用 int* p = NULL; // 禁止:未初始化野指针 int* p;

nullptr 是空指针常量,类型安全,是现代 C++ 首选;NULL 本质是宏 0,存在类型隐患。

三、裸指针的常见分类

1. 普通变量指针

指向普通栈区变量,无需手动释放内存,变量生命周期结束自动失效。

复制代码

int num = 666; int* p = &num;

2. 动态内存指针(堆区指针)

通过 new 在堆区开辟内存,必须手动 delete 释放,否则造成内存泄漏。

复制代码

// 单个变量堆内存 int* p = new int; *p = 10; delete p; // 释放内存 p = nullptr; // 置空,防止野指针 // 数组堆内存 int* arr = new int[5]; arr[0] = 1; delete[] arr; // 数组必须加[]释放 arr = nullptr;

3. 数组指针

数组名本质是数组首元素地址,可以直接赋值给裸指针。

复制代码

int nums[] = {10, 20, 30}; int* p = nums; cout << p[0] << endl; // 10 cout << *p << endl; // 10

4. 结构体指针

常用于自定义数据结构,通过-> 访问成员变量。

复制代码

struct Student { int id; char name[20]; }; Student s = {1001, "Tom"}; Student* p = &s; p->id = 1002; // 指针访问成员用 -> cout << p->id << endl;

四、裸指针算术运算(核心考点)

裸指针支持加减运算,运算单位为指向类型的字节大小,而非单纯+1。

例如:int* 指针 +1,地址实际偏移 4 字节;char* 指针 +1,地址偏移 1 字节。

复制代码

int arr[] = {1,2,3,4,5}; int* p = arr; cout << *p << endl; // 1 cout << *(p + 1) << endl; // 2 cout << *(p + 2) << endl; // 3 // 指针遍历数组 for(int i = 0; i < 5; i++){ cout << *(p + i) << " "; }

指针加减常用来遍历数组、遍历连续内存块,是底层代码高频写法。

五、指针作为函数参数(传地址)

普通变量传参是值传递 ,函数内修改不影响外部;指针传参是地址传递,可以直接修改实参原始数据,也是交换变量的经典写法。

复制代码

void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } int main() { int x = 10, y = 20; swap(&x, &y); cout << x << " " << y << endl; // 20 10 return 0; }

六、裸指针核心优缺点

1. 优点

  • 性能极致:无任何封装开销,内存占用极小,运行速度最快

  • 灵活性高:直接操作内存,适配底层开发、内核、嵌入式、算法高性能场景

  • 通用性强:C/C++ 底层库、第三方库、硬件接口全部兼容裸指针

2. 缺点

  • 手动管理内存:new 必须配对 delete,遗漏会造成内存泄漏

  • 极易出现野指针:未初始化、已释放继续使用、越界访问都会崩溃

  • 内存重复释放:同一块内存多次 delete,程序直接宕机

  • 无自动容错:越界、空指针访问不会主动报错,问题隐蔽难排查

七、裸指针高频致命坑与解决方案

1. 野指针(最高频错误)

指针未初始化,指向随机未知内存,触发未知崩溃。

复制代码

// 错误 int* p; *p = 100; // 野指针崩溃 // 正确 int* p = nullptr; if(p != nullptr){ // 使用前判空 *p = 100; }

2. 内存泄漏

new 开辟堆内存,函数结束或程序退出未 delete,内存无法回收。

复制代码

void test() { int* p = new int[100]; // 未释放,内存泄漏 } // 规范写法:成对使用 new/delete int* p = new int; delete p; p = nullptr;

3. 重复释放内存

同一块内存多次 delete,破坏内存堆结构,程序崩溃。

复制代码

int* p = new int; delete p; delete p; // 错误!重复释放 // 解决:释放后立即置空,空指针delete安全 delete p; p = nullptr; delete p; // 不会报错

4. 指针越界访问

裸指针不做边界检查,越界读写会篡改其他内存,引发诡异 bug。

八、裸指针与智能指针使用场景选择

✅ 优先使用裸指针的场景

  • 高性能算法、极限性能优化场景

  • 嵌入式、操作系统、驱动等底层开发

  • 大型框架底层、库函数封装

  • 短期指针、无需复杂内存管理的临时指针

✅ 优先使用智能指针的场景

  • 业务层开发、长生命周期堆对象

  • 容易遗忘释放内存、复杂对象管理

  • 需要自动回收、避免内存泄漏的场景

九、裸指针开发最佳实践

  • 指针必初始化:定义裸指针默认赋值 nullptr

  • 使用前必判空:避免空指针解引用崩溃

  • new/delete 成对:堆内存申请后必须释放

  • 释放后立即置空:杜绝重复释放、野指针问题

  • 尽量缩短指针生命周期:用完即释放,减少风险

  • 数组释放必须加 \[\]:数组裸指针使用 delete\[\]

十、全文总结

裸指针是 C/C++ 最基础、最高效、也最危险的内存操作工具,核心本质是存储内存地址的变量,通过取地址、解引用、指针运算完成对内存的直接操作。

熟练掌握裸指针,需要记住三大核心:地址存储数据、解引用操作数据、手动管理堆内存 。日常开发中,底层高性能场景用裸指针、业务安全场景用智能指针,严格遵守内存管理规范,即可彻底规避野指针、内存泄漏、重复释放等经典问题。来源:www.ymvpzi.cn

来源:m.ymvpzi.cn

来源:163.ymvpzi.cn

来源:618.ymvpzi.cn

来源:a.ymvpzi.cn

来源:1.ymvpzi.cn

来源:we.ymvpzi.cn

来源:wap.ymvpzi.cn

来源:app.ymvpzi.cn

来源:dnf.ymvpzi.cn

来源:lpl.ymvpzi.cn

来源:h5.ymvpzi.cn

来源:bbs.ymvpzi.cn

来源:b.ymvpzi.cn

来源:c.ymvpzi.cn

来源:web.ymvpzi.cn

来源:cs.ymvpzi.cn

来源:g2.ymvpzi.cn

来源:t1.ymvpzi.cn

来源:i7.ymvpzi.cn