Como uma função pode retornar um struct sem usar malloc? [duplicado]
Eu sou novo em C, apenas uma pergunta sobre como retornar uma estrutura. Eu ouço pessoas dizendo que não há problema em retornar uma estrutura. Por exemplo:
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;
}
Minhas perguntas são:
foo_aestá na foopilha de, portanto, após o footérmino, a pilha será desfeita, o que significa foo_aque não existe realmente na mainpilha da função, o ponteiro main_aque maincontém é na verdade um ponteiro ilegal, então como isso vai funcionar?
Respostas
Uma maneira comum de implementar isso é que a rotina de chamada aloca algum espaço para a estrutura, normalmente na pilha, e passa à rotina chamada um ponteiro para esse espaço. Este parâmetro não é visto no código-fonte C - é parte da convenção de chamada de como as rotinas são chamadas na linguagem assembly. Em seguida, a rotina chamada simplesmente armazena o conteúdo da estrutura no espaço apontado.
Em outras palavras, o código é implementado em grande parte como se tivesse sido escrito:
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;
}
Se a estrutura for pequena, ela pode ser retornada em um registro ou em alguns registros. Tanto a rotina chamada quanto a rotina de chamada estariam usando a mesma convenção de chamada, que teria regras sobre quais estruturas são retornadas em registradores e quais são retornadas por meio de um apontado fornecido pelo chamador.