函数返回struct的实例

时间:2018-01-31 06:57:55

标签: c pointers memory-management struct

struct Temp {};

struct Temp *newTemp() {
    struct Temp *temp = malloc(sizeof(struct Temp));
    return temp;
}


int main() {
    struct Temp *temp = newTemp(); // any problem?
    return 0;
}

从函数(工厂方法)中返回结构实例是否有任何问题。

指针是否无效。我被建议如果你返回一个指针,它应该指向调用者堆栈上的某个东西,一个全局或堆上的东西

3 个答案:

答案 0 :(得分:3)

C结构必须按标准包含至少一个成员,但gcc允许它作为扩展名。

你所做的是合法的 - 你可以返回指向动态分配内存的指针并在其他函数中使用它。

malloc分配的内存的存储时间(分配的存储持续时间)超出了声明的范围。你可以毫无问题地使用它。

预计您将释放已分配的内存并检查malloc的返回值(在发生故障时将您从解除引用中保存为空)。

标准N1570 C11标准也在§7.22.3内存管理功能下提及:

  

.... 分配对象的生命周期从分配延伸到解除分配

答案 1 :(得分:2)

malloc在堆上分配内存。堆上分配的对象具有静态存储持续时间。将指针从函数返回到由malloc分配的对象是有效的。

请注意,您使用的空结构不是标准C. GCC将此功能作为扩展名。

答案 2 :(得分:2)

您有两种方法从函数返回结构:

  1. 返回指向动态分配的struct(您的示例代码)的指针

    动态分配对象的生命周期一直延长,直到取消分配,因此调用者将能够使用它。只是当你不再需要它时,你不能忘记释放它。不这样做被称为内存泄漏。所以固定版本应该是:

    struct Temp {
        int i;          // a struct should not be empty...
    };
    
    struct Temp *newTemp() {
        struct Temp *temp = malloc(sizeof(struct Temp));
        return temp;
    }
    
    int main() {
        struct Temp *temp = newTemp(); // any problem?
        // use temp...
        free(temp);
        return 0;
    }
    
  2. 返回一个临时对象

    struct是C中的第一个类对象,因此您可以直接分配给它。然后,您可以在函数中构建一个结构并返回它(注意:返回指向它的指针实际上会返回一个悬空指针,因为生命周期会在函数返回时结束)。所以另一种方法是:

    struct Temp {
        int i;          // a struct should not be empty...
    };
    
    struct Temp newTemp() {
        struct Temp temp;
        // set values of temp members...
        return temp;
    }
    
    int main() {
        struct Temp temp = newTemp(); // no problem?
        // use temp...
        return 0;
    }
    

    这里的好消息是结构是调用者中的自动对象,因此它不能(也不应该)是free-d。 体面的编译器甚至可以通过让被叫方直接使用来电自动存储来删除副本。