Vamos a empezar por lo sencillo:
Código C++:
Ver originalvoid func(int var)
{
var = 5;
}
int main()
{
int numero= 0;
func(numero);
std::cout << numero;
}
¿Qué se imprime por pantalla? Pues hombre, teniendo en cuenta que
var es una variable local sus cambios no van a afectar en nada a
numero, luego
std::cout imprimirá 0.
Ahora complicamos un poco más el código:
Código C++:
Ver originalvoid func(int* var)
{
*var = 5;
}
void func2(int* var)
{
var = 0;
}
int main()
{
int numero;
int* ptr = №
func(numero);
std::cout << (void*)ptr << " " << *ptr << std::endl;
func2(ptr);
std::cout << (void*)ptr << " " << *ptr << std::endl;
}
El programa ahora imprime la dirección de memoria apuntada por el puntero y el valor almacenado en dicha posición de memoria.
func intenta modificar el valor apuntado por el puntero
var. Al ser var un puntero y apuntar a numero es capaz de modificar su valor correctamente, luego el primer
cout imprimirá una dirección de memoria y el número 5.
Le llega el turno a func2. Esta función intenta modificar la dirección de memoria apuntada por
var, pero claro, si modificas la dirección a la que apunta
var estás modificando la memoria local de
var, luego el cambio no se queda reflejado fuera de
func2. Esto implica que el cambio no tiene efectos en
ptr. Con todo esto lo que sucede es que el programa imprime dos líneas iguales.
Una vez comprendido esto pasamos a tu código:
Código C++:
Ver originalint myfunc(char * obj) {
obj
= (char*)calloc(140,sizeof(char)); strcpy(obj
, "cadena de texto"); return 69; // por ejemplo
}
Como has visto antes, si quieres modificar la dirección apuntada no puedes tirar de un puntero sino en tal caso necesitas un puntero doble (un puntero permite modificar el valor apuntado, un puntero doble permite modificar la dirección apuntada por el puntero simple, etc).
Código C++:
Ver originalint myfunc(char ** obj) {
// modificar obj implicaría cambios locales
// mientras que modificar *obj implica que los cambios se verán fuera de la función
// Si después usa strcpy puedes usar malloc o, mejor aún new
// ya que strcpy finaliza la cadena con '\0'
*obj
= (char*)calloc(140,sizeof(char)); // opción 2. Si usas new libera la memoria con delete
//*obj = new char[140];
strcpy(*obj
, "cadena de texto"); return 69; // por ejemplo
}
Vale, ya tenemos la función terminada... ¿Qué tal si revisamos el uso?
Código C++:
Ver originalchar obj;
int num = myfunc(&obj);
// ahora en num tengo un numero que para mi pregunta es irrelevante, aunque ahora seria 69
// me gustaria usar 'obj'
std::cout << obj;
Fallo gordo en la primera línea. La definición de obj es de tipo char a secas, es decir, no es un puntero. Esto implica por un lado que no va a ser capaz de almacenar nada más que un sólo caracter (olvidate de almacenar cadenas) y por otro que cualquier intento por cambiar su dirección de memoria va a provocar un casque de la aplicación:
Código C++:
Ver originalchar obj;
char* ptr = &obj;
delete ptr; // error
Si queremos que obj pueda manejar memoria dinámica tiene que ser un puntero. Así de simple.
Y no nos debemos olvidar de liberar la memoria reservada cuando ya no la necesitamos. Las buenas costumbres hay que cogerlas desde el principio.
Con todo esto tenemos lo siguiente:
Código C++:
Ver originalchar *obj;
int num = myfunc(&obj); // myfunc espera un puntero doble, por eso usamos el &
std::cout << *obj;
free(obj
); // Si has usado malloc/calloc delete obj; // Si has usado new
obj = 0; // obj=nullptr si prefieres usar el último estándar de C++
Que sería más acorde a lo que tú necesitas.
El código no está ni compilado ni mucho menos probado. He escrito la respuesta sobre la marcha así que no puedo garantizar que esté libre de errores... pero a grandes rasgos parece estar bien.
Un saludo.