Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: PabloPbl en 12 Diciembre 2015, 15:39 pm



Título: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: PabloPbl en 12 Diciembre 2015, 15:39 pm
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
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. void hacerIgualAChauMundo(char *cadena) {
  6.    cadena = "Chau mundo";
  7. }
  8.  
  9. int main() {
  10.    char *cadena = "Hola mundo";
  11.  
  12.    hacerIgualAChauMundo(cadena);
  13.  
  14.    cout << cadena << endl;
  15.  
  16.    return 0;
  17. }
  18.  

Agradecería si me echan una mano.


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: SnzCeb en 12 Diciembre 2015, 16:33 pm
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;
}


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: MAFUS en 12 Diciembre 2015, 16:43 pm
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.


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: user-marcos en 12 Diciembre 2015, 16:58 pm
Si no recuerdo mal los vectores se pasan por referencia

Código
  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4.  
  5. void hacerIgualAChauMundo(char cadena[]) {
  6.   strcpy(cadena, "Chau mundo");
  7. }
  8.  
  9. int main() {
  10.    char cadena[] = "Hola mundo";
  11.  
  12.    hacerIgualAChauMundo(cadena);
  13.  
  14.    cout << cadena << endl;
  15.  
  16.    return 0;
  17. }
  18.  


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: geeke en 12 Diciembre 2015, 19:43 pm
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.


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: fary en 12 Diciembre 2015, 20:01 pm
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:

Código
  1. // Juan fary (mDrinky)
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <windows.h>
  6.  
  7. void hacerIgualAChauMundo(char * cadena) {
  8.    char * adios = "Chau mundo";
  9.    DWORD ViejaPro;
  10.  
  11.    VirtualProtect(cadena, strlen(adios),PAGE_READWRITE,&ViejaPro); // obtenemos derechos de acceso
  12.  
  13.    memcpy(cadena,adios,strlen(adios)); // Copiamos nuestra nueva cadena
  14. }
  15.  
  16. int main() {
  17.    char *cadena = "Hola mundo";
  18.  
  19.    hacerIgualAChauMundo(cadena);
  20.  
  21.    printf("%s\n",cadena);
  22.  
  23.    return 0;
  24. }
  25.  

saludos.


Título: Re: ¿Como cambiar un puntero de caracteres desde otra función?
Publicado por: PabloPbl en 13 Diciembre 2015, 14:49 pm
Muchas gracias a todos por esta valiosa información, la tendré en cuenta  ;-)

Salu2.