C++中vector指针指向对象无法访问,触发Segmentation Fault求助
问题分析与解决方案
核心错误原因
你代码里的段错误根源是变量遮蔽(Variable Shadowing):
- 在
graph类的构造函数中,你重新定义了一个局部变量std::vector<node*> * P_nodes_vec,直接盖住了类的成员变量P_nodes_vec。 - 构造函数执行完毕后,这个局部变量会被销毁,但类的成员变量
P_nodes_vec自始至终都是未初始化的野指针,test方法里访问这个野指针自然会触发段错误。 - 另外
node的构造函数也存在错误:你写的int node_integer = 1;是定义了一个局部变量,根本没给类的成员变量node_integer赋值,不过后来调用了set_node_integer,这个问题暂时没暴露,但属于错误写法。
修复步骤
- 修正graph构造函数的变量遮蔽问题
去掉构造函数里的变量声明,直接给类成员变量赋值:graph() { // 去掉前面的std::vector<node*> *,直接给成员变量赋值 P_nodes_vec = generate_vec_nodes(); }; - 修复node构造函数的赋值错误
把构造函数里的局部变量定义改成给成员变量赋值(用初始化列表更规范):node(void) : node_integer(1) {}; // 或者写成 node(void){ node_integer = 1; }; - 可选优化:避免裸指针,使用智能指针
作为新手,建议尽早习惯用C++标准库的智能指针(比如std::unique_ptr)管理堆内存,避免手动管理带来的泄漏和野指针问题。比如把std::vector<node*>改成std::vector<std::unique_ptr<node>>,graph里的成员改成std::unique_ptr<std::vector<std::unique_ptr<node>>> P_nodes_vec,RAII机制会自动帮你处理内存释放。
修正后的完整代码
#include <iostream> #include <vector> class node { public: friend class graph; // 修复构造函数:用初始化列表给成员变量赋值 node(void) : node_integer(1) {}; void set_node_integer(int x){ node_integer = x; }; int get_node_integer(){ return node_integer; }; private: int node_integer; }; // 生成存储node指针的vector并返回其指针 std::vector<node*> * generate_vec_nodes() { std::vector<node*> * new_P_nodes_vec = new std::vector<node*>; for(int i = 0 ; i < 169 ; i++) { node* next_node = new node(); next_node->set_node_integer(i); new_P_nodes_vec->push_back(next_node); }; return new_P_nodes_vec; }; class graph { private: std::vector<node*> * P_nodes_vec; public: // 修复构造函数:去掉局部变量声明,直接给成员变量赋值 graph() { P_nodes_vec = generate_vec_nodes(); }; void test(void) { std::cout << "Hello 1" << std::endl; std::cout << (*P_nodes_vec)[0]->get_node_integer() << std::endl; std::cout << "Hello 2" << std::endl; }; }; int main() { graph my_graph; std::cout << "\n\n"; my_graph.test(); std::cout << "\n\n"; std::cout << "End of computations"; std::cout << "\n\n"; return 0; };
补充说明
- 变量遮蔽是新手高频踩坑点,在类的成员函数里,尽量不要定义和成员变量同名的局部变量;如果必须用,要明确用
this->访问成员变量(比如this->P_nodes_vec = generate_vec_nodes();)。 - 当前代码没有
delete任何堆内存,会造成内存泄漏,后续学习智能指针可以彻底解决这个问题。
内容的提问来源于stack exchange,提问作者Rico C
相关产品推荐
相关产品推荐

