如何将C++内层类成员存入外层类指针数组并避免悬空指针
问题根源
你改写的代码崩溃有两个核心问题:
- 成员
test* arr是未初始化的野指针,没有分配任何可访问的内存空间,直接访问arr[0]属于非法内存访问,这是运行报错的直接原因。 - 你误解了
test* arr的类型定义:test* arr是指向test实例的指针,用来表示元素为test实例的动态数组;如果你要的是存储test指针的指针数组,成员类型应该定义为test** arr。
正确实现方案
方案1:动态数组存储test实例(匹配你现有test* arr的定义)
这种方案下数组里直接存test对象实例,不需要额外给每个对象单独开内存,只需要给数组整体分配空间即可:
#include <iostream> using namespace std; class k { public: class test { private: int x; public: test(int a) { x = a; } void print() { cout << x << endl; } // 补充默认构造函数,因为new[]创建数组会调用默认构造 test() : x(0) {} }; // 构造函数初始化动态数组,这里示例存4个元素 k() { arr = new test[4]; arr_size = 4; } // 析构函数释放数组,避免内存泄漏 ~k() { delete[] arr; arr = nullptr; // 释放后置空,避免悬空指针 } void output(); test* arr; int arr_size; // 记录数组长度,避免越界访问 }; void k::output() { arr[0] = test(5); arr[0].print(); // 可以继续给其他元素赋值 arr[1] = test(10); arr[1].print(); } int main() { k m; m.output(); return 0; }
方案2:指针数组存储test*(符合你说的「指针数组」需求)
如果确实需要数组里存指针,每个指针指向独立的test对象,按如下方式实现:
#include <iostream> using namespace std; class k { public: class test { private: int x; public: test(int a) { x = a; } void print() { cout << x << endl; } }; // 构造函数初始化指针数组,示例存4个指针 k() { arr = new test*[4]; arr_size = 4; // 初始化所有指针为nullptr,避免野指针 for(int i=0; i<arr_size; i++) { arr[i] = nullptr; } } // 析构函数先释放每个test对象,再释放指针数组 ~k() { for(int i=0; i<arr_size; i++) { delete arr[i]; // delete空指针是安全操作,不用额外判空 arr[i] = nullptr; } delete[] arr; arr = nullptr; } void output(); test** arr; // 指针数组的类型是test** int arr_size; }; void k::output() { // 用new创建动态对象,赋值给指针数组元素 arr[0] = new test(5); // 指针访问成员用->运算符 arr[0]->print(); } int main() { k m; m.output(); return 0; }
避免悬空指针、内存泄漏的注意事项
- 动态内存必须配对使用:
new对应delete,new[]对应delete[],不要混用 - 所有指针使用前必须初始化,要么指向合法内存,要么置为
nullptr,禁止野指针直接访问 - 指针指向的内存被释放后,立刻将指针置为
nullptr,避免后续误访问产生悬空指针 - 优先使用标准库容器(如
std::vector)代替裸指针动态数组,容器会自动处理内存分配、扩容、释放逻辑,不需要手动操作 - 优先使用智能指针(如
std::unique_ptr、std::shared_ptr)代替裸指针,智能指针会自动管理对象生命周期,不需要手动释放,从根源避免悬空指针和内存泄漏
内容的提问来源于stack exchange,提问作者Vito Metvet
相关产品推荐
相关产品推荐

