【问题标题】:Why are pointers inside of a vector changing when being returned from a function?为什么从函数返回时向量内的指针会发生变化?
【发布时间】:2020-06-26 20:45:11
【问题描述】:

在我的实际应用程序中,我使用双连接边列表来存储平面的子部分,但我尝试减少代码以显示我的问题。

我有一个包含自定义结构的列表,我需要将其转换为指向存储在列表中的对象的指针向量。当我这样做时,在发生转换的函数内部,我的向量中的指针与指向列表中对象的指针相同,但在函数外部(当我将返回值存储在变量中时)指针变了。为什么会出现这种情况?它与移动/复制值有关吗?怎么了?

感谢您的帮助!

struct MyStruct
{
    MyStruct* my_other_struct;
}

static std::vector<MyStruct*> structPointers(
    std::list<MyStruct> structs)
{
    std::vector<MyStruct*> struct_pointers;
    struct_pointers.reserve(structs.size());
    std::transform(structs.begin(), structs.end(),
        std::back_inserter(struct_pointers),
        [](MyStruct& ms){ return &ms; });

    for (const MyStruct* ms : struct_pointers)
    {
        // this seems to print out the correct memory address
        std::cout << ms << std::endl;
    }

    return struct_pointers;
}

int main()
{
    std::list<MyStruct> structs;
    structs.push_back(Struct());
    structs.push_back(Struct());
    structs.front().my_other_struct = &structs.back()
    structs.back().my_other_struct = &structs.front()

    std::vector<MyStruct*> struct_pointers = structPointers(structs)

    // I get two different addresses printed out here and I don't understand why
    std::cout << &structs.front() << std::endl;
    std::cout << struct_pointers.front() << std::endl;

    // I get two different addresses printed out here and I don't understand why
    std::cout << &structs.back() << std::endl;
    std::cout << struct_pointers.back() << std::endl;

    return 0;
}

【问题讨论】:

    标签: c++ pointers copy move-semantics


    【解决方案1】:

    您需要通过引用接受structs,否则您在函数内创建的指针将引用原始MyStruct 对象的副本。

    static std::vector<MyStruct*> structPointers(
        std::list<MyStruct>& structs) // <-- take by reference
    

    这是demo

    【讨论】:

    • 我已经盯着这个看了好几天了。我讨厌错过这样的东西。谢谢!这让我等待接受答案。
    • #@ChristianErmann 没问题。您的帖子有许多语法错误(主要是缺少分号)。您应该确保您的程序能够编译并产生您所描述的行为。这样你会得到更好的帮助。
    【解决方案2】:

    您通过值而不是通过引用传递列表,因此在调用函数时您会获得列表的新副本,并且该副本在从函数返回时被销毁。发生的情况是,您复制函数的列表,因此副本具有与原始元素不同的元素,然后将副本元素的地址附加到返回的向量中,因此地址属于副本而不是原始 .向量中的指针也会悬空(指向被破坏的对象)

    解决方案:通过引用而不是按值传递:

    static std::vector<MyStruct*> structPointers(
        std::list<MyStruct>& structs)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 2013-01-29
      • 2020-02-19
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      相关资源
      最近更新 更多