C ++从&Vector获取struct返回指向非初始化struct的指针

时间:2015-05-22 10:13:35

标签: c++ pointers vector struct

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

如果a是int而不是向量而不是a.push_back(1);,则使用a = 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;
}

2 个答案:

答案 0 :(得分:3)

您正在尝试使用临时Foo对象初始化指针:

Foo * foo1Ptr = &structFromVector();

您的编译器应该拒绝此代码(使用临时地址。)

如果要编译,在此行之后,可以想象foo1Ptr将指向不存在的对象(它将是悬空指针)。取消引用它会调用未定义的行为。不过,讨论一个不合规的实现会做什么是非常具有推测性的。

因此,不要将指针绑定到临时,即使你的编译器允许你这样做。

一个解决方案,可能是您打算做的,是返回对向量元素的引用:

Foo& structFromVector() {
    return fooList[0];
}

只要您不对使其无效的向量执行操作(例如,增加其大小以使其重新分配),此引用就有效。

答案 1 :(得分:1)

因为代码中有未定义的行为

下面:

Foo * foo1Ptr = &structFromVector();

structFromVector返回一个临时对象,foo1Ptr成为指向此临时对象的指针。在;之后,这个临时对象被销毁,指针被称为悬空(换句话说 - 它变得无效)。

在第二种情况下,

Foo foo2 = structFromVector();
Foo * foo2Ptr = &foo2;

foo2现在是此临时对象的副本foo2Ptr指向此副本。因此,指针有效(foo1Ptr无效)。 副本 alive 直到范围结束 - 在这种情况下,直到main的{​​{1}}。

它与}“合作”的原因同样是UB(未定义行为) - 任何事情都可能发生。

编辑好吧,它似乎是格式错误的代码,因为编译器确实应该拒绝该代码。但事实并非如此,它仍然是UB。