508 字
1 分钟
【CPP】内存与指针
进程地址空间(典型模型)
高地址 +------------------+ | 命令行参数/环境 | +------------------+ | 栈 ↓ | 局部变量、函数调用帧 | ... | | 堆 ↑ | 动态分配(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;规则:
| 规则 | 说明 |
|---|---|
new 配 delete | 单对象 |
new[] 配 delete[] | 数组 |
勿重复 delete | 未定义行为 |
勿 delete 非 new 分配的内存 | 未定义行为 |
对空指针 delete | 安全,无操作 |
与 malloc 区别:new 分配后会调用构造函数,delete 前会调用析构函数。
指针基础(补充)
int x = 10;int* p = &x; // p 存 x 的地址*p = 20; // 解引用修改 xint* 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 应出现在资源管理类的实现内部,业务代码优先智能指针。
原笔记相关勘误
- “动态指的时程序运行时” → 应为动态指的是程序运行时分配。
- C 中
const“存在符号表、改地址仍从符号表读” —— 属于编译器实现细节,标准只保证const语义;以标准与可移植行为为准。 - C++ “不支持 VLA”正确;
vector等容器用于运行期决定长度。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
