Jokabeludoido:
Deixa eu ver se entendi. Retornando o ponteiro para o arranjo declarado dentro do escopo da função, não há garantias de que, voltando ao escopo global, os valores estejam lá de fato. Eles podem ser alterados por outro processo ou procedimento neste meio tempo. É iso?
Sim senhor. Vou fabricar um exemplo para você ter exatamente uma idéia do que ocorre.
#include <stdio.h>
#include <stdlib.h>
int *ingenuo (int x) {
int var [10];
int i;
for (i = 0; i < sizeof(var) / sizeof(var[0]); ++i)
var[i] = x;
return var; /* nunca retorne o endereço de um array local! */
/* O Microsoft C dá até uma mensagem "warning C4172: returning address of local variable or temporary */
}
double* esperto (double x) {
double var [5];
double *ret;
int i;
for (i = 0; i < sizeof(var) / sizeof(var[0]); i++)
var[i] = x;
ret = (double *) calloc (sizeof(var)/sizeof(var[0]), sizeof(var[0]));
memcpy (ret, var, sizeof(var));
return ret;
}
void print (const char* msg, int elementos[], int n) {
int i;
puts (msg);
for (i = 0; i < n; ++i)
printf ("%d, ", elementos[i]);
puts("");
}
main (int argc, char*argv[]) {
int* elementos;
double* outros_elementos;
elementos = ingenuo (10);
print ("Depois do retorno de ingenuo:", elementos, 10);
outros_elementos = esperto (2.7182818284590452353602874713527);
print ("Depois do retorno de esperto:", elementos, 10);
free (outros_elementos); /* tudo que alocar, desaloque */
}
O que você esperaria que ele imprimisse para o valor retornado por “ingenuo”? Seria “10, 10, 10, 10, 10, 10, 10, 10, 10, 10,”.
Só que ele imprime, dependendo da opção de compilação:
Depois do retorno de ingenuo:
10, 4208064, -208566343, -2, 4200412, 4198670, 4354048, 4354048, 8, 1245040,
Depois do retorno de esperto:
-[telefone removido], 4208064, -208566343, -2, 4200412, 4198670, 4354048, 4354048, 8, 1245040,
ou então
Depois do retorno de ingenuo:
10, 4205888, -[telefone removido], -2, 4200252, 4198622, 4255744, 4255744, 8, 1245040,
Depois do retorno de esperto:
-[telefone removido], 4205888, -[telefone removido], -2, 4200252, 4198622, 4255744, 4255744, 8, 12
45040,
ou ainda outra coisa qualquer (compile esse código com algum outro compilador, que você vai ver ainda outros resultados diferentes.)
Mude alguma opção de compilação (tire ou ponha o modo debug, use otimização ou não, etc.
E vai ver ainda outros resultados bizarros.
Portanto, certos warnings são na verdade erros, e muito graves. Esse é um deles.