1
char * trocear(int num){
    char *salida;
    int i=0;
    while(num/10>0){    
        *(salida+i)=num%10+'0';
        num=num/10;
        i++;
    }
    *(salida+i)=num+'0';
    i++;
    *(salida+i)='\0';
    return salida;
}

Esta funcion es para darle la vuelta al orden de los digitos de un int y pasarlo a char, de 123456 a "654321\n". Cuando la invoco desde el main con esto el programa no hace nada y no da ningun error

char *n;
n=trocear(123456);
cout<<*(n+2) //por ejemplo
hugoboss
  • 129
  • 11

2 Answers2

5

Tu programa tiene problemas gravísimos, es raro que siquiera te funcione de manera inocua.


Variables usadas fuera de su ámbito.

En la función trocear creas la variable salida de tipo puntero a caracter char * y devuelves ese puntero, el cuál, dado que pertenece a la función trocear cuando sales de dicha función deja de existir y se pierde. Usar los valores de una variable que ha dejado de existir es un comportamiento indefinido.

Aritmética de punteros mal usada.

La variable salida es un puntero que no apunta a ningún dato existente. Los punteros existen para apuntar a datos (lee este hilo) y sólo cuando apuntan a algo tienen sentido. En tu caso creas el puntero pero no le asignas valor:

char *salida;

Lo que implica que apunta a un lugar desconocido de la memoria (las variables no inicializadas reciben un valor indeterminado al crearse), desde ese lugar desconocido haces aritmética de punteros para apuntar a diferentes puntos partiendo de un origen desconocido:

 *(salida+i)=num%10+'0';

Esa línea se traduce como: "Desde el punto en el que estás, avanza i posiciones y en ese punto escribe el valor indicado", el problema es que sin saber el punto desde el que empiezas, difícilmente sabrás el punto al que vas... esto es otro comportamiento indefinido.


Propuesta.

Si quieres trabajar con punteros (yo no lo haría, pero si es un requerimiento necesitaremos adherirnos al mismo), necesitarás usar memoria dinámica en lugar de memoria automática (la memoria automática se libera al abandonar el ámbito en que se crea, la memoria dinámica se libera a mano) así que tu función trocear debería tener este aspecto:

char * trocear(int num) {
    // Un entero de 32 bits puede contener números de hasta 10 dígitos
    char *salida = new char[11];

    // hacer cosas...

    return salida;
}

Con esta propuesta, la memoria que has creado en trocear deberá ser liberada tras su uso:

char *n = trocear(123456);
cout << n;
delete[] n; // <---- MUY IMPORTANTE

Pero hacer esto es un dolor de cabeza importante, te aconsejo usar punteros inteligentes:

std::unique_ptr<char[]> trocear(int num) {
    // Un entero de 32 bits puede contener números de hasta 10 dígitos
    auto salida = std::make_unique<char[]>(11);

    for (int digito = 0; num; ++digito)
    {
        salida[digito] = '0' +  num % 10;
        num /= 10;
    }

    return salida;
}

El puntero inteligente se encargará de liberar la memoria al finalizar su uso, liberándote de la responsabilidad de hacerlo a mano:

auto n = trocear(123456);
cout << n.get();

Puedes ver el código funcionando en Wandbox.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
0

No estoy del todo de acuerdo con las respuestas que te han dado por eso te doy la mía. Hay muchas maneras de hacer tu código con punteros manteniendo el mismo propósito, me parece que este tema es funadmental para entender la programación en c++ y entender la programación en sí, aunque hayan lenguajes que abstraen al programador de los punteros, en realidad eso es lo que siempre se hace en la máquina. por eso decidí hacer un ejemplo lo mas parecido a tu lineamiento aunque hayan muchas maneras de hacerlo.

char* trocear(int num){ 
    char *salida = new char[20];
    char c;
    int mod;
    int i=0;
    while (num>0){

        mod = num%10;           
        salida[i] = mod+48; 
        num = (num-mod)/10;     
        i++;
    }
    salida[i] = '\0';

    return salida;

}

int main(){

    int num = 123456;

    char *cadenaTroceada = trocear(num);

    cout<<cadenaTroceada<<endl;

    return 0;
}

Luego si en el main deseas un caracter en específico recuerda que puedes tratar a tu puntero como un vector. Te dejo una forma comentada y una forma sin comentar.

int main(){

    int num = 123456;

    char *cadenaTroceada = trocear(num);    

    //cout<<cadenaTroceada[2]<<endl;    

    cadenaTroceada += 2;
    cout<<*cadenaTroceada<<endl;

    return 0;
}

Te dejo un enlace de unos tutoriales donde explican el tema https://www.youtube.com/watch?v=dqoCI2Gina8

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • **No estás borrando la memoria solicitada** en `trocear`, eso es un terrible fallo que provoca fugas de memoria. Por otro lado, puedes pedir la memoria dinámica e iniciarla a `0` en el mismo momento (`char *salida = new char[20]{};`, nótese las llaves) lo cuál te ahorra poner el `\0`. Pides 20 caracteres pero sólo necesitarás 11 (2^32 tiene 10 dígitos). – PaperBirdMaster Dec 02 '18 at 12:39