关于C中的返回函数的问题

时间:2011-09-07 13:43:55

标签: c struct

我是一名学习过程序员的java程序员。有一个问题归档功能。这有什么区别:

main()
{
    struct person myperson;

    myperson = myfunction();

    return;
}

struct person myfunction()
{
     struct person myPerson;
     myPerson.firstname = "John";
     myPerson.lastname = "Doe";
     return myPerson;
}

VS

main()
{
    struct person *myperson;

    myperson = myfunction();

    return;
}

struct person* myfunction()
{
     struct person *myPerson;
     myPerson = malloc(sizeof(struct person));
     myPerson->firstname = "John";
     myPerson->lastname = "Doe";
     return myPerson;
}

这些在C中合法吗?你会选择一个而不是另一个。 非常感谢你们!

10 个答案:

答案 0 :(得分:7)

第一个版本在堆栈上分配对象,并返回副本。第二个版本在上创建对象,并向其返回指针(这与Java引用最接近,但内存不会自动释放)。你不应该忘记稍后在返回的指针上调用free()

是的,你的主要功能很糟糕。它应该是

int main(void)
{    
    ...
    return 0;
}

我建议您阅读a good C book。这是你要问的基本内容。

答案 1 :(得分:7)

第一个代码示例:
你在堆栈的myfunction()中创建一个struct并返回它。然后,您创建另一个堆栈结构,然后复制第一个到第二个。第一个被摧毁。当你超出范围时,第二个将被自动销毁。 实际上已经创建了 2个结构

第二个代码示例:
你在myfunction()中创建一个结构,然后只复制地址。 main中的struct实际上是相同的struct。
在这里只创建一个结构

两个代码示例都可以工作,但是对于以后你必须显式释放为结构分配的内存,以避免内存泄漏,但性能应该更好,因为你不需要复制结构!

修改
如@Mat所述:这当然忽略了malloc()的开销,而小结构则不然。

答案 2 :(得分:4)

答案 3 :(得分:3)

两者都合法,都有效。

第一个版本更简单,您可以避免处理内存分配和释放。

第二个版本对更大的结构体的性能会更好,因为你可以避免将整个结构放在堆栈上以便将其移交。

答案 4 :(得分:3)

我实际上会选择第三种方式。让调用者担心提供存储空间(自动或动态分配):

void myfunction(struct person* myPerson)
{
     myPerson->firstname = "John";
     myPerson->lastname = "Doe";
}

可以使用自动或动态分配的变量调用该函数:

struct person autoperson;
myfunction(&person);

struct person dynamic_person = malloc(sizeof struct person);
myfunction dynamic_person);

答案 5 :(得分:1)

第一个将在堆栈上分配struct person,并将其副本传回,然后释放原始文件。第二个将在堆上分配它并将指针传递给已分配的位置,并且不会释放它。

答案 6 :(得分:0)

第一个在堆栈上分配变量。来自myfunction的person对象从函数中复制并返回效率较低,但是你不能得到一个好的内存泄漏。

第二个示例将指针(*)返回给动态分配的person对象(使用malloc)。 malloc分配的person对象永远不会被销毁,除非你明确地调用free(),你没有 - 所以你有内存泄漏。

你需要在C中显式释放内存,它没有像Java这样的垃圾收集。

答案 7 :(得分:0)

第一个选项在堆栈上创建一个结构,当返回它时,它会被复制到main()函数中定义的结构中。还复制了字段。对于较大的结构,这可能是一项昂贵的操作。

第二个选项分配动态内存,返回时不会被复制。您必须free()指针以避免内存泄漏。

当然这取决于你的需求,但对于更重要和更长寿的物品,我会选择第二种选择。我还建议编写分配/初始化函数和相应的释放函数。 (见下文原因)

问题是你在myfunction()中设置的2个字符串在函数外部是无效的,因为它们也是在堆栈上创建的。您必须使用strdup()或类似函数才能使此失败。当然,为了不让内存泄漏,你需要free() strdup个指针,就像使用malloc()一样。

答案 8 :(得分:0)

在第一个代码中,myPerson是类型struct person的对象,由实现本身管理(*)。在第二个代码中,它是struct person *类型的对象(指向struct person的指针)。在第二个代码中,对象本身必须由程序员(mallocreallocfree)管理。

此外,在第一个代码中,对象本身被复制几次,而在第二个代码中,“仅”复制指针。 通常,指针比结构类型的对象小得多。

使用第二种方法,但请记住free对象。

更好的是,在父函数中创建对象并将指针传递给函数:sruct person *myfunction(struct person *data) { /* ... */ }

带对象管理的

(*)我的意思是它创建和删除的时间和内容

答案 9 :(得分:0)

第一个:

main()
{
    // create a person struct on the stack
    struct person myperson;
    // copy the struct returned by myfunction to myperson.
    myperson = myfunction();
}

struct person myfunction()
{
    // create a person struct on the stack.
    struct person myPerson;
    myPerson.firstname = "John";
    myPerson.lastname = "Doe";
    // return the myPerson struct. After myFunction returns, the memory
    // holding the myPerson struct on the stack will be freed.
    return myPerson;
}

第二个:

main()
{
    // create a pointer to a person struct on the stack
    struct person *myperson;
    // assign the pointer returned by myfunction to myperson
    myperson = myfunction();
}

struct person* myfunction()
{
    // create a pointer to a person struct on the stack
    struct person *myPerson;
    // allocate memory for a person struct in dynamic memory and set myPerson
    // to point to that memory. This memory will remain valid until it's freed by
    // a call to the "free" function. Using malloc is much slower than creating
    // an object on the stack. There is also the added performance cost of
    // freeing the allocated memory at a later stage.
    myPerson = malloc(sizeof(struct person));  
    myPerson->firstname = "John";
    myPerson->lastname = "Doe";
    // return the myPerson pointer
    return myPerson;
}