对检索到的矢量进行操作时出现分段故障
Segmentation Fault when operating on retrieved vector
我对C++有点陌生,我有一个问题很好奇。有一段时间,我遇到了分割错误,尽管我最终做到了,但我想知道为什么以前没有。这就是我所拥有的:
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
class A {
private:
int num;
public:
A(int i){this->num=i;}
int getNum(){return this->num;}
};
class B {
private:
vector<A*> list;
public:
vector<A*> getList(){return this->list;}
void addA(A* i){this->getList().push_back(i);}
string as_a_string(){
stringstream result;
cout << "Flag1" <<endl; //only for debug, this prints
for (vector<A*>::iterator x = this->getList().begin(); x != this->getList().end(); ++x) {
cout << "Flag2" << endl; //only for debug, this prints
A* w = *x;
cout << "Flag3" << endl; //only for debug, this prints
result << w->getNum() << " ";
cout << "Flag4" << endl; //only for debug, this does not print
}
return result.str();
}
};
int main() {
A* a = new A(4);
B* b = new B();
b->addA(a);
cout << b->as_a_string() << endl;
return 0;
}
我通过用this->list
替换this->getList()
的每个实例来解决我的问题(共有3个实例;一个在B::addA(A*)
中,两个在B::as_a_string()
中的for循环定义中)。为什么使用成员本身而不是通过方法访问它会影响该程序的工作?
问题是B::getList()
按值返回列表,因此实际返回的是B::list
的副本,而不是原始列表本身。
在您的循环中:
for (vector<A*>::iterator x = this->getList().begin();
x != this->getList().end(); ++x)
首先,为这个临时列表获取一个begin迭代器。每次检查条件时,都会将其与不同的临时列表对象的结束迭代器进行比较。
简单的解决方法是让B::getList()
通过引用返回列表:
vector<A*>& getList();
由于getList
正在返回list
的临时副本,因此当您尝试对其进行迭代时,list
会再次消失。
有几种不同的方法来处理这个问题:
- 只需使用
list
(不需要使用this->
——它不是PHP、Python或某些必须通过this
/self
指针引用成员的语言) - 让
getList
返回对向量的引用。(vector<A*>& getList() { ... };
) - 使用局部变量作为副本
但是,选项3在addA
中没有帮助,它要求您在ORIGINAL列表上操作(目前,您的push_back
在list
的临时副本上操作,该副本在push_back
返回后立即销毁,因此它实际上根本不会向实际的list
成员变量添加任何内容)。
就我个人而言,我会将您的内部代码更改为直接使用list
,并保持getList
返回一份副本,这样,如果某个外部函数想要获得列表,它就可以了。
编辑:您没有删除在main
中创建的A*和B*对象,这也是在泄漏内存。
您的代码:
class B {
private:
vector<A*> list;
public:
vector<A*> getList(){return this->list;}
void addA(A* i){this->getList().push_back(i);}
正在临时调用push_back(),因为getList()按值返回。调用add()后,成员变量列表保持不变。您可以更改getList()函数签名以返回如下引用:
vector<A*>& getList(){return this->list;}
老实说,使用用于避免问题的解决方案可能会更好,因为提供一个返回对实现详细信息的引用的公共访问器是您通常希望避免的事情。
- 分段故障(堆芯转储)矢量
- 为什么在popback()操作之后,它仍然打印完整的矢量
- C++中的动态铸造故障
- 数组的指针从不分段故障
- 重载操作程序时出错>>用于类中的字符串 memebr
- vscode g++链路故障:体系结构x86_64的未定义符号
- 访问被拒绝后,c++中的故障保护代码
- 对字符串进行位操作
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 我可以在 C++ 中的函数体之外进行操作吗?
- MPI突然停止了对多个核心的操作
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 对字符数组中的元素执行逐位操作
- 如何在directx/c++中进行平移/缩放操作
- 逐位操作的隐式类型转换
- 二进制搜索树操作程序错误:分割故障(核心倾倒)
- 分段故障 C++ 最有可能在 strtok 操作中
- 大规模套接字操作的分段故障
- 对检索到的矢量进行操作时出现分段故障
- 基本阵列操作中的分段故障错误