从函数返回结构体和内存分配

4
让我们考虑这样一个例子:
typedef struct {
  int hours;
  int minutes;
  int seconds; 
} Time;

Time createTime() {
    Time time;
    time.hours = ....
    time.hours = ....
    time.hours = ....
    return time
}

void doSomething(){

    while(true){
        Time newTime = createTime(); 
        // do something with time....
    }
}

关于内存分配,我有几个问题

  1. createTime() 方法为什么不返回 NULL? #time 是一个局部变量,因此当方法超出范围时应该被销毁。
  2. doSomething() 方法内多次调用 createTime(),会导致内存泄漏吗?

我认为在结构体中,访问说明符默认是全局的。 - Suchit kumar
3个回答

9
createTime不能使用 return NULL;,它会返回一个Time对象。
在C和C++中,函数通过值进行返回。这意味着当你写下return time;时,会创建一个临时对象,称为“返回值”。该对象是从你返回的表达式复制而来的。在C中,这是逐成员复制,在C ++中,则使用复制构造函数。因此,代码Time newTime = createTime();的事件顺序如下:
  1. createTime()内部创建并填充time
  2. 创建返回值,并将其值从time复制过来
  3. 销毁time
  4. 创建newTime,使用返回值作为初始化程序。
  5. 销毁返回值
实际上这涉及到大量的复制和销毁,但编译器可以对其进行优化(在C和C++中),使得最终结果是createTime可以直接将time构造到newTime的内存空间中,而不需要使用临时对象。实际上,你可能会发现应用了各种不同级别的优化。
注意:在C++11中,将上述的“复制”替换为“复制或移动”。

6
您不返回指针或引用,而是通过值返回,这意味着结构被复制。没有动态内存分配,所有操作都由编译器在编译时处理,由于没有动态分配,因此不存在内存泄漏的可能性。
唯一的缺点是您无法返回NULL以表示没有返回任何内容。您必须始终返回一个有效的结构。

3
通过使用 return time; [带有 ;],你返回的是而不是地址,并将该返回值收集到调用者的变量中。返回值被简单地复制到 newTime 中。
这是完全有效的。在这种情况下,没有动态内存使用。在这个上下文中没有内存泄漏。
接下来,createTime() 不能返回NULL,因为返回类型已指定为Time类型。它必须返回一个有效的Time类型的结构体变量。此外,NULL只适用于指针类型。但是,如果你愿意,你可以返回一个所有成员都初始化为-1的结构体,以报告一些错误。[根据你的结构体定义,成员是int]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接