我正在尝试将一个空的struct指针传递给一个名为&#34的函数;初始化"作为输出参数,然后在函数完成后,我可以检索结构指针指向的对象。一些意想不到的行为发生了,我不太明白。
以下是我的代码:
static void initialize(complex_struct*& infoPtr)
{
complex_struct myInfo;
infoPtr = &myInfo;
// some other codes that modify the contents of myInfo
infoPtr->input_components = 3;
}
static void myfunction()
{
complex_struct* infoPtr = nullptr;
initialize(infoPtr);
std::cout << infoPtr->input_components << std::endl;
}
这个输出是一个任意的大整数。但我期待打印整数3。
限制: 我无法修改complex_struct;它是一个需要使用的third_party结构。 另外,我需要将initialize()作为一个单独的函数的原因是我正在对complex_struct的内存分配进行性能测量。因此,将initialize()中的第一行代码移动到myfunction()并不是一个理想的解决方案。
答案 0 :(得分:6)
您正尝试在其范围函数之外使用指向局部变量的指针。在您的示例中,退出函数后,myInfo
内的initialize()
实例将被删除,您记住的地址将指向随机垃圾内存。你永远不应该使用指向范围之外的局部变量的指针。
如何解决问题?最简单的方法是抛弃指针,而不是通过非const引用传递你的结构。代码如下所示:
void initialize(complex_struct& info)
{
// some other codes that modify the contents of myInfo
info.input_components = 3;
}
void myfunction()
{
complex_struct info;
initialize(info);
std::cout << info.input_components << std::endl;
}
建议的代码中存在一个微妙的缺陷:有效的信息被初始化两次。第一次创建它的实例(complex_struct info
),第二次在initialize()函数内创建。它在这个例子中没有任何明显的效果(info
在堆栈上分配,我不认为它有任何非平凡的构造函数)但在其他设置中可能会有更大的问题。在这种情况下初始化它的最好方法是从初始化函数返回结构,并依靠copy-elision来优化掉所有副本。插图代码:
complex_struct initialize()
{
complex_struct info;
// some other codes that modify the contents of myInfo
info.input_components = 3;
return info;
}
void myfunction()
{
complex_struct info = initialize();
std::cout << info.input_components << std::endl;
}
答案 1 :(得分:2)
您正在返回指向堆栈框架中对象的指针。函数返回时,该对象被删除。你在myfunction
中有一个悬空指针。
解决问题的方法:
从堆中分配内存
static void initialize(complex_struct*& infoPtr)
{
infoPtr = new complex_struct ;
infoPtr->input_components = 3;
}
确保在调用函数中释放内存。
使用对象而不是指针
static void initialize(complex_struct& info)
{
info.input_components = 3;
}
并更改其用法:
static void myfunction()
{
complex_struct info;
initialize(info);
std::cout << info.input_components << std::endl;
}