C++ 从 vector 获取结构 &返回指向非初始化结构的指针
C++ getting struct from vector with & returns pointer to non-initialized struct
函数structFromVector()
从结构体的向量返回一个结构体。如果你编译下面的代码,那么foo1Ptr->a
是一个空向量,但foo2Ptr->a
是一个唯一元素为1的向量。为什么在第一种情况下没有初始化结构?
如果a
是整型而不是矢量,并且使用a = 1;
代替a.push_back(1);
,则foo1Ptr->a
和foo2Ptr->a
都等于1。为什么在这种情况下有效而在第一种情况下无效?
struct Foo {
std::vector<int> a;
Foo() {
a.push_back(1);
}
};
std::vector<Foo> fooList;
Foo structFromVector() {
return fooList[0];
}
int main() {
fooList.push_back(Foo());
Foo * foo1Ptr = &structFromVector();
Foo foo2 = structFromVector();
Foo * foo2Ptr = &foo2;
}
您正在尝试用临时Foo
对象初始化指针:
Foo * foo1Ptr = &structFromVector();
你的编译器应该拒绝这段代码(获取临时。的地址)
如果要编译,在这行之后,可以想象foo1Ptr
将指向一个不存在的对象(它将是一个悬空指针)。取消引用会调用未定义的行为。然而,讨论一个不符合标准的实现会做什么是相当投机的。
因此,即使编译器允许,也不要将指针绑定到临时对象。
一个解决方案是返回对vector元素的引用,这可能是您想要做的:
Foo& structFromVector() {
return fooList[0];
}
只要不对vector对象执行使其无效的操作(例如,增加vector对象的大小从而重新分配vector对象),该引用就有效
因为你的代码中有未定义的行为
:
Foo * foo1Ptr = &structFromVector();
structFromVector
返回一个临时对象,foo1Ptr
成为指向这个临时对象的指针。在;
之后,这个临时对象被销毁,指针被称为悬空(换句话说,它变得无效)。
第二种情况
Foo foo2 = structFromVector();
Foo * foo2Ptr = &foo2;
foo2
现在是这个临时对象的副本,foo2Ptr
指向这个副本。因此,指针是有效的(而foo1Ptr
无效)。复制将存活直到作用域的结束-在本例中,直到main
的}
。
它与int
"工作"的原因是,再次,UB(未定义行为)-任何事情都可能发生。
EDIT嗯,这看起来是错误格式的代码,因为编译器真的应该拒绝该代码。但由于没有,它仍然是UB。
- 多成员Constexpr结构初始化
- 为什么用结构初始化数组需要指定结构名称
- 使用指定的初始值设定项聚合匿名结构初始化
- 不同的类或结构初始化方法之间的性能差异是什么?
- 如何在结构初始化中获取成员C++
- C++正确的结构初始化
- 使用大括号进行结构初始化
- 内部结构初始化不起作用 - C++
- 使用嵌套结构初始化并集
- 使用匿名结构初始化联合
- 结构初始化语法
- 结构初始化的 C++ 向量
- C++嵌套结构初始化和访问成员
- 结构初始化中的常量正确性
- 使用 C++ 中的自定义元素进行 Const 结构初始化
- 如何在结构C++初始化内置数组
- Visual C++ 模板类成员结构初始化语法糖
- C++结构初始化
- C 在结构初始化过程中带有内部阵列的奇怪错误
- 此C/C 的结构初始化器如何使用足够的字段工作