Para entender mejor tu problema, quita los punteros. Imagínate este código:
Código C++:
Ver originalint func( )
{
return 4;
}
int main( )
{
int variable = 10;
variable = func( );
}
¿Qué valor almacena
variable al final del programa? queda claro que valdrá 4.
Vale, pero esto era muy facil... y si le ponemos un puntero doble? Veamos
Código C++:
Ver originalint** func( )
{
return (int**)4;
}
int main( )
{
int** variable = (int**)10;
variable = func( );
printf( "%d\n", (int)variable
); }
He añadido algunos cast para evitar warnings, por lo demás queda claro que el programa es el mismo... ¿qué valor se imprimirá ahora? Nuevamente, la respuesta vuelve a ser 4.
Un operador de asignación sustituye un valor por otro... así de simple. Si estamos usando variables por valor ( int, char, double, etc ) se machacará el valor de la variable... si usamos punteros, dado que los punteros almacenan posiciones de memoria, se sustituirá la posición de memoria gestionada por el puntero.
En tu programa lo que sucede es que en la línea 4 haces una reserva de memoria y almacenas la posición de dicha reserva en
variable. Pero luego, en la línea 6 haces que
variable apunte a otra región de memoria, que será la que te devuelve
myfunction. Esto provoca que la memoria reservada en la línea 4 ya no sea accesible (no tienes ninguna variable que te diga dónde se encuentra), por lo que no podrás liberar esa memoria... esto es una fuga de memoria o laguna de memoria y es uno de los problemas más comunes al trabajar con memoria dinámica.
¿Soluciones? tranquilo que las hay. Te expongo un par de ellas:
1. Haces que
myfunction se encargue de reservar la memoria:
Código C:
Ver originalchar** myfunction( )
{
char** to_return
= (char**)malloc(10*sizeof(char*));
// ... operaciones sobre to_return ...
return to_return;
}
int main( )
{
char ** variable = myfunction();
return 0;
}
2.
myfunction recibe como parámetro el puntero sobre el que debe operar. Al recibir un puntero, los cambios que se hagan en la memoria apuntada se verán reflejados al abandonar la función.
Nota que ahora, myfunction recibe también el número de elementos, esto te permite trabajar con arrays de diferentes tamaños.
Código C:
Ver originalvoid myfunction( char** matriz, int numElementos )
{
// ... operaciones sobre matriz ...
}
int main( )
{
char ** variable
= (char**)malloc(10*sizeof(char*));
myfunction( variable, 10 );
return 0;
}
Y, por cierto, que no se te olvide liberar toda la memoria que hayas reservado. Empieza a adquirir esta costumbre desde el principio para evitar sorpresas desagradables con programas más grandes.
Un saludo.