508 字
1 分钟
【CPP】内存与指针
2026-03-19

进程地址空间(典型模型)#

高地址 +------------------+
| 命令行参数/环境 |
+------------------+
| 栈 ↓ | 局部变量、函数调用帧
| ... |
| 堆 ↑ | 动态分配(new/malloc)
+------------------+
| BSS(未初始化静态)|
+------------------+
| 数据段 .data | 已初始化全局/静态
+------------------+
| 代码段 .text |
低地址 +------------------+

说明:具体布局因 OS/ABI 略有差异;栈向低地址增长、堆向高地址增长是常见教学模型。

分配方式时机存储区域释放
静态/栈编译期或进入作用域栈 / 静态区自动
动态运行时 new/malloc手动 delete/free 或智能指针
int arr[10]; // 栈上,大小须编译期常量
int* heap = new int[10];
delete[] heap;

C 风格:malloc / free#

void* malloc(size_t size);
void* calloc(size_t nmemb, size_t size); /* 分配并置零 */
void* realloc(void* ptr, size_t size);
void free(void* ptr);
  • 返回 void*,在 C++ 中应转为具体类型指针。
  • 不会调用构造函数;不会自动类型安全。
  • new/delete 不要混用同一块内存。

C++ 风格:new / delete#

int* p = new int(10);
delete p;
int* arr = new int[10]{1,2,3};
delete[] arr;

规则

规则说明
newdelete单对象
new[]delete[]数组
勿重复 delete未定义行为
deletenew 分配的内存未定义行为
对空指针 delete安全,无操作

与 malloc 区别new 分配后会调用构造函数,delete 前会调用析构函数。

指针基础(补充)#

int x = 10;
int* p = &x; // p 存 x 的地址
*p = 20; // 解引用修改 x
int* q = nullptr; // C++11 推荐 nullptr,而非 NULL
  • 野指针:未初始化或已释放仍使用。
  • 悬垂指针:指向已销毁对象(局部变量地址、已 delete 的内存)。
  • 内存泄漏new 后未 delete,且无智能指针管理。

智能指针(RAII)#

用类对象自动管理堆内存,析构时释放。

类型所有权典型场景
std::unique_ptr<T>独占默认首选,不可拷贝,可移动
std::shared_ptr<T>共享引用计数多处共享同一资源
std::weak_ptr<T>不增加计数,观察 shared_ptr打破循环引用
auto p = std::make_unique<int>(100); // 推荐,异常安全
auto sp = std::make_shared<std::string>("hi");
// 不要 delete unique_ptr.get() 返回的裸指针后再让智能指针析构

原则:现代 C++ 中,裸 new/delete 应出现在资源管理类的实现内部,业务代码优先智能指针。

原笔记相关勘误#

  1. “动态指的时程序运行时” → 应为动态指的是程序运行时分配。
  2. C 中 const “存在符号表、改地址仍从符号表读” —— 属于编译器实现细节,标准只保证 const 语义;以标准与可移植行为为准。
  3. C++ “不支持 VLA”正确;vector 等容器用于运行期决定长度。
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【CPP】内存与指针
https://lysj.work/posts/studynotes/cpp/cpp内存与指针/
作者
Sekiro
发布于
2026-03-19
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录