首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C或C++中返回结构安全吗?

在C或C++中返回结构安全吗?
EN

Stack Overflow用户
提问于 2012-03-07 03:52:40
回答 11查看 70.7K关注 0票数 86

我所理解的是这不应该这样做,但我相信我见过这样的例子(注意代码不一定在语法上是正确的,但想法是存在的)

代码语言:javascript
复制
typedef struct{
    int a,b;
}mystruct;

然后这里有一个函数

代码语言:javascript
复制
mystruct func(int c, int d){
    mystruct retval;
    retval.a = c;
    retval.b = d;
    return retval;
}

我知道,如果我们想做这样的事情,应该总是返回一个指向malloc‘’ed struct的指针,但我敢肯定,我已经看到过这样的例子。这是正确的吗?就我个人而言,我总是返回一个指向malloc‘’ed struct的指针,或者只是通过引用传递函数并修改其中的值。(因为我的理解是,一旦函数的作用域结束,任何用于分配结构的堆栈都可以被覆盖)。

让我们在问题中添加第二个部分:这是否会因编译器而异?如果是这样,那么最新版本的桌面编译器: gcc、g++和Visual Studio的行为是什么?

对这件事有什么想法?

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2012-03-07 03:54:36

这是完全安全的,这样做没有错。另外:它不随编译器的不同而变化。

通常,当你的结构不是太大时(就像你的例子),我认为这种方法甚至比返回一个恶意锁定的结构更好(malloc是一个开销很大的操作)。

票数 82
EN

Stack Overflow用户

发布于 2012-03-07 03:54:57

绝对安全。

您是按值返回的。如果通过引用返回,会导致未定义的行为。

代码语言:javascript
复制
//safe
mystruct func(int c, int d){
    mystruct retval;
    retval.a = c;
    retval.b = d;
    return retval;
}

//undefined behavior
mystruct& func(int c, int d){
    mystruct retval;
    retval.a = c;
    retval.b = d;
    return retval;
}

您的代码片段的行为是完全有效和定义的。它不随编译器的不同而变化。好了!

就我个人而言,我总是返回一个指向

结构的指针

你不应该这样做。你应该尽可能避免动态分配内存。

,或者只是通过引用传递函数并修改其中的值。

这个选项是完全有效的。这是一个选择的问题。通常,如果您希望在修改原始结构时从函数返回其他内容,则可以执行此操作。

,因为我的理解是,一旦函数的作用域结束,用来分配结构的任何堆栈都可以被覆盖

这是错误的。我的意思是,它在某种程度上是正确的,但是你返回了你在函数中创建的结构的副本。Theoretically.在实践中,RVO可以而且很可能会发生。阅读有关返回值优化的内容。这意味着,尽管当函数结束时retval似乎超出了作用域,但它实际上可能是在调用上下文中构建的,以防止额外的复制。这是一个编译器可以自由实现的优化。

票数 75
EN

Stack Overflow用户

发布于 2012-03-07 03:57:30

当您离开函数时,函数中mystruct对象的生命周期确实结束了。但是,您是通过return语句中的值传递对象的。这意味着将对象从函数复制到调用函数中。原始对象消失了,但副本仍然存在。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9590827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档