new person[num]分配连续内存但不调用构造函数,pod类型可用,非pod可能未定义;释放须用delete[];指针数组需两层分配与释放;推荐std::vector替代裸指针。

用 new Person[num] 分配连续结构体数组,但注意它不调用构造函数
如果你只需要一块连续内存来存 num 个 Person 对象(且 Person 是 POD 类型,比如只含 int、char* 等原始成员),可以直接用 new Person[num]。它在堆上分配一块足够大的连续空间,等价于 C 的 malloc(sizeof(Person) * num)。
但关键点是:new Person[num] 不会为每个元素调用 Person 的构造函数——哪怕你定义了默认构造函数。这意味着:
-
char* name成员不会自动初始化为nullptr,而是未定义值(野指针) - 如果结构体里有
std::string或其他非 POD 成员,这种写法可能引发未定义行为 - 释放时必须用
delete[] p,不能漏掉[]
用 new Person*[num] + 循环 new Person() 构建指针数组
这是管理“不确定数量 + 每个对象需独立构造”的典型做法,比如每个 Person 需要动态分配姓名字符串。你需要两层分配:
- 先用
Person** p_array = new Person*[num]分配指针数组 - 再对每个下标循环:
p_array[i] = new Person(此时会调用构造函数) - 如果
Person构造函数里做了name = new char[...],那每块name内存也都是独立的
释放顺序必须严格逆序:先遍历 p_array[i] 调用 delete p_array[i],再 delete[] p_array。漏掉任意一层都会内存泄漏。
delete[] 和 delete 混用会直接崩溃
这是最常踩的坑。错误示例如下:
Person* p1 = new Person[10]; // 连续数组 Person** p2 = new Person*[5]; // 指针数组 // 错误释放: delete p1; // ❌ 应该是 delete[] p1 delete[] p2[0]; // ❌ p2[0] 是单个 Person*,应 delete p2[0]
原因在于:new[] 分配的内存头部通常记录了元素个数,供 delete[] 正确析构多个对象;而 delete 只析构一个。混用会导致堆元数据错乱,轻则程序异常终止,重则静默损坏后续内存。
用 std::vector 替代裸指针数组更安全
除非你在嵌入式环境或明确禁止 STL,否则优先用 std::vector<person></person> 或 std::vector<:unique_ptr>></:unique_ptr>:
-
std::vector<person></person>自动管理连续内存,构造/析构由容器保证 -
std::vector<:unique_ptr>></:unique_ptr>等价于手动管理的指针数组,但释放完全自动,不怕遗漏 - 两者都不需要手写
delete,也不用纠结[]问题
唯一要注意的是:如果 Person 含裸 char* 成员,仍需在析构函数里 delete[] name——智能指针不管结构体内部怎么管内存,只管它自己持有的那个指针。
真正容易被忽略的点是:结构体里有指针成员时,拷贝和赋值会浅拷贝,导致多处指向同一块堆内存。这时候要么禁用拷贝(= delete),要么写深拷贝构造函数和赋值运算符——这比分配/释放本身更容易出问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











