在函数中创建struct对象并传递其指针

时间:2015-09-30 20:15:35

标签: c++ pointers struct

我正在尝试将一个空的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()并不是一个理想的解决方案。

2 个答案:

答案 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;
}