我所理解的是这不应该这样做,但我相信我见过这样的例子(注意代码不一定在语法上是正确的,但想法是存在的)
typedef struct{
int a,b;
}mystruct;然后这里有一个函数
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的行为是什么?
对这件事有什么想法?
发布于 2012-03-07 03:54:36
这是完全安全的,这样做没有错。另外:它不随编译器的不同而变化。
通常,当你的结构不是太大时(就像你的例子),我认为这种方法甚至比返回一个恶意锁定的结构更好(malloc是一个开销很大的操作)。
发布于 2012-03-07 03:54:57
绝对安全。
您是按值返回的。如果通过引用返回,会导致未定义的行为。
//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似乎超出了作用域,但它实际上可能是在调用上下文中构建的,以防止额外的复制。这是一个编译器可以自由实现的优化。
发布于 2012-03-07 03:57:30
当您离开函数时,函数中mystruct对象的生命周期确实结束了。但是,您是通过return语句中的值传递对象的。这意味着将对象从函数复制到调用函数中。原始对象消失了,但副本仍然存在。
https://stackoverflow.com/questions/9590827
复制相似问题