为什么从函数返回时向量内部的指针会发生变化?
Why are pointers inside of a vector changing when being returned from a function?
在我的实际应用中,我使用双向连接的边列表来存储平面的分段,但我试图减少代码来显示我的问题。
我有一个包含自定义结构的列表,我需要将其转换为指向列表中存储的对象的指针向量。当我这样做时,在发生转换的函数内部,我的向量中的指针与指向列表中对象的指针相同,但在函数外部(当我将 return 值存储在内部时一个变量)指针已经改变。为什么会这样?它与 moving/copying 值有关吗?怎么了?
感谢大家的帮助!
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;
}
您需要通过引用接受 structs
,否则您在函数内创建的指针指的是原始 MyStruct
对象的副本。
static std::vector<MyStruct*> structPointers(
std::list<MyStruct>& structs) // <-- take by reference
这是一个demo。
您是按值而不是按引用传递列表,因此您在调用函数时会获得列表的新副本,并且此副本会在 return 从函数中销毁。发生的事情是您复制函数的列表,因此副本具有与原始元素不同的元素,然后将副本元素的地址附加到您 return 的向量,因此地址属于副本而不是原本的 。向量中的指针也将悬空(指向被破坏的对象)
解决方案:按引用传递而不是按值传递:
static std::vector<MyStruct*> structPointers(
std::list<MyStruct>& structs)
在我的实际应用中,我使用双向连接的边列表来存储平面的分段,但我试图减少代码来显示我的问题。
我有一个包含自定义结构的列表,我需要将其转换为指向列表中存储的对象的指针向量。当我这样做时,在发生转换的函数内部,我的向量中的指针与指向列表中对象的指针相同,但在函数外部(当我将 return 值存储在内部时一个变量)指针已经改变。为什么会这样?它与 moving/copying 值有关吗?怎么了?
感谢大家的帮助!
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;
}
您需要通过引用接受 structs
,否则您在函数内创建的指针指的是原始 MyStruct
对象的副本。
static std::vector<MyStruct*> structPointers(
std::list<MyStruct>& structs) // <-- take by reference
这是一个demo。
您是按值而不是按引用传递列表,因此您在调用函数时会获得列表的新副本,并且此副本会在 return 从函数中销毁。发生的事情是您复制函数的列表,因此副本具有与原始元素不同的元素,然后将副本元素的地址附加到您 return 的向量,因此地址属于副本而不是原本的 。向量中的指针也将悬空(指向被破坏的对象)
解决方案:按引用传递而不是按值传递:
static std::vector<MyStruct*> structPointers(
std::list<MyStruct>& structs)