C++ 从 vector 获取结构 &返回指向非初始化结构的指针

C++ getting struct from vector with & returns pointer to non-initialized struct

本文关键字:结构 初始化 指针 返回 vector 获取 C++      更新时间:2023-10-16

函数structFromVector()从结构体的向量返回一个结构体。如果你编译下面的代码,那么foo1Ptr->a是一个空向量,但foo2Ptr->a是一个唯一元素为1的向量。为什么在第一种情况下没有初始化结构?

如果a是整型而不是矢量,并且使用a = 1;代替a.push_back(1);,则foo1Ptr->afoo2Ptr->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。