自定义对象与数组的自由存储区指针差异及内存泄漏问询
问题解答
先修正代码里的类型匹配问题(原代码中int*无法直接指向Object类型的动态对象/数组,属于笔误),修正后代码如下:
void func (Object* p); int main(){ Object* arr = new Object[10]; Object* obj = new Object; func(arr); func(obj); // 需手动释放动态内存,否则会泄漏 delete[] arr; delete obj; return 0; }
1. 调用func(arr)的问题
- func的参数是值传递,函数内部的
p是arr的副本,它确实指向arr的首元素,但只是一个新的局部指针变量(指向同一块内存)。 - 绝对不能在func末尾删除
p:这块内存是main中用new[]分配的,释放权属于main。如果在func里执行delete[] p,会导致main里的arr变成悬空指针,后续操作触发未定义行为;若误写delete p,对数组使用delete同样是未定义行为。 - 不需要处理局部指针
p:p是函数内的局部变量,函数执行结束后会自动销毁,它本身不占用动态分配的内存,不存在泄漏问题。真正的泄漏风险是main中分配的内存未被释放。
2. 调用func(obj)的问题
- 逻辑和数组场景完全一致:func里的
p是obj的副本,指向同一个Object对象。 - 不能在func里删除
p:否则main里的obj会变成悬空指针,释放动态内存的责任在main,不在func。 - 局部指针
p无需删除,函数结束后自动销毁,不会造成泄漏。
3. 改为void func(Object*& p)后能否用于数组
可以正常使用。数组名arr会隐式转换为指向首元素的指针,引用传递只是让func里的p直接绑定到main里的arr指针本身(而非创建副本)。不管是指向数组首元素的指针还是单个对象的指针,都可以作为指针引用的参数传递,因此完全适用于数组场景。
内存泄漏预防核心要点
- 遵循谁分配谁释放原则:用
new/new[]分配的内存,必须由负责分配的代码用delete/delete[]释放。 - 不要随意在函数内释放传入指针指向的内存,除非函数的明确职责是接管该内存的生命周期。
- 优先使用智能指针(如
std::unique_ptr、std::shared_ptr),自动管理内存,避免手动delete导致的泄漏或悬空指针问题。
内容的提问来源于stack exchange,提问作者Adam Smith
相关产品推荐
相关产品推荐

