指针向量解引用迭代器时出现段错误
Segfault when dereferencing iterator for vector of pointers
我有一个对象指针向量
std::vector<Element*> elements;
当遍历vector时,我想对迭代器进行双引用,以便调用对象的方法。
std::cout << (*it)->getName() << std::endl;
这会导致段故障。相关代码如下:
我认为问题在于我如何初始化向量,因为我可以将for循环移动到方法initialize()
中,它工作得很好。在takeTurn()
中,向量大小合适,指针包含正确的地址。这是否意味着被指向的对象正在被过早地销毁?
main.cpp:
#include <vector>
#include <iostream>
#include "Element.h"
std::vector<Element*> elements;
void initialize() {
Element ice = Element("ice",1);
Element fire = Element("fire",2);
elements.push_back(&ice);
elements.push_back(&fire);
}
void takeTurn() {
std::vector<Element*>::iterator it;
for(it = elements.begin(); it != elements.end(); ++it) {
std::cout << (*it)->getName() << std::endl;
}
}
int main() {
initialize();
takeTurn();
return 0;
}
Element.h:
#include <string>
class Element {
public:
Element(std::string name, int id);
int getID() { return id_; }
std::string getName() { return name_; }
private:
int id_;
std::string name_;
};
Element.cpp:
#include "Element.h"
Element::Element(std::string name, int id) {
name_ = name;
id_ = id;
}
初始化函数被破坏了。您创建本地对象,然后将它们的地址压入向量。但是当函数返回时,这些对象将被销毁,指针也不再有效。除非您需要多态,否则最简单的修复方法就是创建Element对象的向量,而不是指针。
std::vector<Element> elements;
...
elements.push_back(Element("ice",1));
elements.push_back(Element("fire",2));
如果你需要多态性,那么使用智能指针。
std::vector<std::unique_ptr<Element>> elements;
...
elements.push_back(std::unique_ptr<Element>(new Element("ice",1)));
elements.push_back(std::unique_ptr<Element>(new Element("fire",2)));
如果你继续使用原始指针,那么你需要一些方法来确保对象的持久性,也许是通过new
来分配它们。然后,您需要确保在使用完这些指针的每个指针上调用delete
。我不推荐你走这条路。
将指向局部变量的指针传递给vector:
Element ice = Element("ice",1);
Element fire = Element("fire",2);
elements.push_back(&ice);
elements.push_back(&fire);
当你退出函数时,ice
和fire
不再存在,所以你剩下的是悬空指针。
这个问题的解决方案取决于你是否真的需要一个指针向量。std::vector<Element>
:
std::vector<Element> elements;
然后elements.push_back(Element("ice",1));
elements.push_back(Element("fire",2));
将悬空指针压入vector:
void initialize() {
Element ice = Element("ice",1);
Element fire = Element("fire",2);
elements.push_back(&ice);
elements.push_back(&fire);
}
这里冰和火是局部变量。将地址压入vector,然后当到达final}时,它们都被销毁。当你稍后引用这个无效指针的行为是未定义的。
vector存储的是指向堆栈上创建的局部变量的指针。当函数结束时,这些变量所占用的内存将被回收。如果你试图访问内存,你会得到一个段错误。
void initialize() {
Element ice = Element("ice",1); // Local variable.
Element fire = Element("fire",2); // Local variable.
elements.push_back(&ice);
elements.push_back(&fire);
} // Ice and fire disappear.
为堆中的元素分配内存:
void initialize() {
Element *ice = new Element("ice",1);
Element *fire = new Element("fire",2);
elements.push_back(ice);
elements.push_back(fire);
}
记住在完成后释放内存!
typedef std::vector<Element *>::iterator EIter;
for (EIter it = elements.begin(); it != elements.end(); ++it) {
delete *it;
}
相关文章:
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 如何摆脱C ++中的分段错误错误?
- Clang 8 带有静态 constexpr 和数组的链接器错误 - 错误是什么以及如何解决它?
- 为什么每当我尝试运行此链接列表删除功能时都会收到分段错误错误?
- 如何解决分段错误错误C++
- 作为参数模板的模板类:MSVC 错误 - 错误 C2977:模板参数过多 (C++98)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 卷曲给出分段错误错误
- 无法访问 Arduino 结构字段。错误"退出状态 1。xxxx 不命名类型"
- 错误错误 C2872:"布尔值":kinect.h 的不明确符号
- C++打印模板容器错误(错误:"运算符<<"的不明确重载)理解?
- 结构的分割错误错误
- 为什么此代码返回分段错误错误?
- 错误错误:无法编译内置功能
- 分段错误错误C++
- C++ 1Z 错误:错误:演绎指南中声明中的显式限定
- 使用对数据类型的向量的哈希表中的分段错误错误
- 为什么此代码会导致分段错误错误
- JNA结构字段值错误
- C++段故障错误