【问题标题】:How can a function return a struct without using malloc? [duplicate]函数如何在不使用 malloc 的情况下返回结构? [复制]
【发布时间】:2021-02-04 22:15:12
【问题描述】:

我是 C 新手,只是一个关于返回结构的问题。我听到人们说返回一个结构是可以的。例如:

struct MyObj{
   int x,y,z;
};

struct MyObj foo(){
    struct MyObj foo_a;
    foo_a.x = 10;
    foo_a.y = 10;
    foo_a.z = 10;

    return foo_a;
}        

int main () {
    struct MyObj main_a = foo();
    return 0;
} 

我的问题是:

foo_afoo的栈中,所以在foo完成后,栈将被展开,这意味着foo_a实际上并不存在于main函数的栈中,指针@987654327 @ 那main 持有其实是一个非法指针,那它是怎么工作的呢?

【问题讨论】:

  • main holds is actually an illegal pointer 但没有指针。 main_a 不是指针
  • 返回一个局部变量的副本是可以的——你总是用返回int的函数来做这件事。不好的是试图返回一个指向局部变量的指针;指针的副本返回OK,但它指向的数据不再存在,导致问题。
  • @JonathanLeffler 是的,我知道,这就是为什么我问为什么人们说不使用 malloc 就可以返回结构
  • 因为您返回的是结构的副本,而不是指向结构的指针。就像您返回 int 的副本,而不是指向 int 的指针。
  • @JonathanLeffler 对不起,我不明白,你的意思是foo 函数通过在main 方法的堆栈中写入值来返回结构的副本main_a 是?

标签: c struct return-value allocation


【解决方案1】:

实现这一点的一种常见方式是调用例程为结构分配一些空间,通常在堆栈上,并向被调用例程传递一个指向该空间的指针。这个参数在 C 源代码中是看不到的——它是汇编语言中例程调用约定的一部分。然后被调用的例程简单地将结构的内容存储在指向的空间中。

换句话说,代码的实现很大程度上就像是编写的一样:

void foo(struct MyObj *temporary){
    struct MyObj foo_a;
    foo_a.x = 10;
    foo_a.y = 10;
    foo_a.z = 10;
    *temporary = foo_a;
}        

int main () {
    struct MyObj temporary;
    foo(&temporary);
    struct MyObj main_a = temporary;
    return 0;
} 

如果结构很小,可以在一个寄存器或几个寄存器中返回。被调用例程和调用例程都将使用相同的调用约定,该约定将规定哪些结构在寄存器中返回,哪些结构通过调用者提供的指针返回。

【讨论】:

  • 抱歉还是没明白,struct MyObj a; 只存在于foo 的栈中,一旦 foo 完成,它的栈也没有了,所以main_a 指向的东西没有'不存在?
  • 我认为您遇到困难的概念是main_a 不是指针。将代码中的语句return foo_a 视为对结构中的所有字段执行复制操作。它没有分配指向结构的指针。
猜你喜欢
  • 2012-04-20
  • 2021-12-07
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多