¿Como cambiar un puntero de caracteres desde otra función?

Iniciado por PabloPbl, 12 Diciembre 2015, 15:39 PM

0 Miembros y 1 Visitante están viendo este tema.

PabloPbl

Quiero conseguir cambiar el valor de un puntero de char mediante una función, pasandole por parámetro un puntero, pero no funciona, la función no me cambia el valor.


Esto es lo que tengo echo:
Código (cpp) [Seleccionar]

#include <iostream>

using namespace std;

void hacerIgualAChauMundo(char *cadena) {
   cadena = "Chau mundo";
}

int main() {
   char *cadena = "Hola mundo";

   hacerIgualAChauMundo(cadena);

   cout << cadena << endl;

   return 0;
}


Agradecería si me echan una mano.

SnzCeb

Las cadenas son un tanto especiales, ya que cuando pasas (char *) estás pasado el valor de la cadena, no su referencia. Para modificar una cadena tienes que pasar una doble referencia.

#include <iostream>

using namespace std;

void hacerIgualAChauMundo(char **cadena) {
    *cadena = "Chau mundo";
}

int main() {
    char *cadena = "Hola mundo";

    hacerIgualAChauMundo(&cadena);

    cout << cadena << endl;

    return 0;
}

MAFUS

#2
Muy buenas.

Las constantes de cadena se guardan en una posición de memoria que C dedica para las constantes. Cuando asignas así una cadena a un puntero no varías una posición de memoria sino que apuntas a una zona de memoria que no va a cambiar en todo el programa.

Tu función recoge un puntero y por tanto podrías modificar en dicha función a lo que hay en esa zona de memoria que apunta el puntero, pero el puntero en sí, al ser una copia, aunque lo cambies dentro de la función, en main seguirás teniendo el valor original. Si quieres cambiarlo de la forma que quieres hacerlo pásalo con un puntero a puntero, entonces podrás cambiar hacia a donde apunta.

Una cosa a tener en cuenta: si lo haces de esta forma la cadena que dejes huérfana será un lastre: su memoria estará ocupada y el programa no la va a poder reclamar para darle otro uso, pero no podrás acceder a ella más pues habrás perdido su dirección al dar otro valor al puntero.

user-marcos

Si no recuerdo mal los vectores se pasan por referencia

Código (cpp) [Seleccionar]

#include <iostream>
#include <cstring>
using namespace std;

void hacerIgualAChauMundo(char cadena[]) {
   strcpy(cadena, "Chau mundo");
}

int main() {
    char cadena[] = "Hola mundo";

    hacerIgualAChauMundo(cadena);

    cout << cadena << endl;

    return 0;
}

geeke

En C++ una cadena literal es considerada una constante, por lo tanto es imposible modificarla, en cambio en C es posible hacerlo pero nunca lo hagas, porque estarías invocando comportamiento indefinido, esto ocurre por dos razones:

- Los compiladores almacenan varias cadenas literales idénticas en la misma dirección, por lo que la modificación de uno podría cambiar los otros también.

- Las cadenas literales se almacenan con frecuencia en la memoria de sólo lectura, si intentas escribir aquí obtendrás un error en tiempo de ejecución.

fary

Como te dice Coper, vas a tener problemas para hacerlo porque la memoria es de solo lectura pero dandole privilegios lo puedes lograr. Aparte de eso si la cadena nueva es mas grande que la vieja puedes tener problemas porque puedes sobreescribir otros datos, en tu caso esto no pasará ya que las dos cadenas son identicas.

Aquí te dejo como lograrlo:

// Juan fary (mDrinky)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void hacerIgualAChauMundo(char * cadena) {
   char * adios = "Chau mundo";
   DWORD ViejaPro;

   VirtualProtect(cadena, strlen(adios),PAGE_READWRITE,&ViejaPro); // obtenemos derechos de acceso

   memcpy(cadena,adios,strlen(adios)); // Copiamos nuestra nueva cadena
}

int main() {
   char *cadena = "Hola mundo";

   hacerIgualAChauMundo(cadena);

   printf("%s\n",cadena);

   return 0;
}


saludos.
Un byte a la izquierda.

PabloPbl

Muchas gracias a todos por esta valiosa información, la tendré en cuenta  ;-)

Salu2.