添加到 std::shared_ptr 的向量会导致段错误
Adding to std::shared_ptr of vector causes segfault
我有这个示例程序。我要做的就是在矢量本身中包含的对象之间共享矢量的实例,以便它们可以从容器中操作(添加其他对象,删除自己(。
#include <iostream>
#include <memory>
#include <vector>
class SimpleClass {
private:
std::shared_ptr<std::vector<SimpleClass>> objects;
public:
SimpleClass (std::shared_ptr<std::vector<SimpleClass>> _objects): objects { _objects } {}
void grow () {
std::cout << "growing" << std::endl;
for (int i { 0 }; i < 10; ++i) {
std::cout << "about to add a new object" << std::endl;
std::cout << "current simple_objects size: " << objects->size() << std::endl;
objects->push_back(SimpleClass(objects));
std::cout << "added a new object" << std::endl;
}
}
};
int main () {
auto simple_objects = std::make_shared<std::vector<SimpleClass>>();
for (int i { 0 }; i < 10; ++i) {
simple_objects->push_back(SimpleClass { simple_objects });
}
std::cout << "simple_objects size: " << simple_objects->size() << std::endl;
for (auto &obj: *simple_objects) {
obj.grow();
}
return 0;
}
经过一些迭代后,该程序存在一个Segmentation Fault 11
:
simple_objects size: 10
growing
about to add a new object
current simple_objects size: 10
added a new object
about to add a new object
current simple_objects size: 11
added a new object
about to add a new object
current simple_objects size: 12
added a new object
about to add a new object
current simple_objects size: 13
added a new object
about to add a new object
current simple_objects size: 14
added a new object
about to add a new object
current simple_objects size: 15
added a new object
about to add a new object
current simple_objects size: 16
added a new object
about to add a new object
Segmentation fault: 11
该程序可以在这里进行测试:https://www.onlinegdb.com/rJHSik8Hf
导致分段错误的原因是什么以及如何预防它?
问题是您在仍在使用类时重新分配(复制/移动(该类。
我猜矢量分配了 16 个插槽。现在,您要添加项目 17。这意味着向量需要分配更大的数组并复制/移动现有项目。
这有效,但请考虑当前项目(此(。它在旧阵列中。它被移动/复制,旧数组被销毁。所以现在这指向你刚刚解除分配的内存,你得到段错误(幸运(。
您可能想要的是调整矢量大小不会更改项目。您可以将项目包装在 std::unique_ptr 中,它会正常工作。
其他替代方法是固定数组的大小,以便不进行大小调整,或者不从数组中的对象修改数组。
在堆栈上创建shared_ptr
的本地副本应该可以解决问题。(只是 ptr,而不是整个向量(
void grow () {
auto localObjects = objects;
std::cout << "growing" << std::endl;
for (int i { 0 }; i < 10; ++i) {
std::cout << "about to add a new object" << std::endl;
std::cout << "current simple_objects size: " << localObjects->size() << std::endl;
localObjects->push_back(SimpleClass(objects));
std::cout << "added a new object" << std::endl;
}
}
您还应该在迭代时创建一个副本,因为您在迭代时修改了向量。您的代码现在可以运行,没有 seg 错误。https://onlinegdb.com/H1lNlcgOSG
auto localCopy = *simple_objects;
for (auto &obj: localCopy) {
obj.grow();
}
相关文章:
- 编写代码时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++段故障错误