[C con Clase] Error: Fallo de segmentación
Steven R. Davidson
vze266ft en verizon.net
Mar Ene 22 22:38:16 CET 2008
Hola José Luis,
JoseL wrote:
> Hola,
>
> Estoy practicando con un programa que hace conversiones entre
> sistemas numéricos. La función DectoBase valdría para convertir un
> entero decimal 'numdec' en una cadena 'numbase' que representa el
> mismo número en base 'base'. La función retorna un puntero a dicha
> cadena.
>
> El caso es que puedo compilarlo(wx-devcpp), pero cuando lo ejecuto el
> programa se cierra abruptamente. El código tiene más o menos esta
> pinta:
>
> #include <iostream>
> using namespace std;
>
> typedef unsigned long long int TIPO1;
> typedef unsigned short int TIPO2;
>
> const char DIGITOS[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
> '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
>
> char* DectoBase(TIPO1 numdec, TIPO2 base);
> //...
>
> int main()
> {
> TIPO1 num=45763;
> char *result;
> //...
> result = DectoBase(num, 16);
> cout << result << endl;
> //...
> cin.get();
> return 0;
> }
>
> char* DectoBase(TIPO1 numdec, TIPO2 base)
> {
> TIPO2 resto;
> TIPO2 i = 0, j;
> char *numbase;
>
> while(numdec >= base)
> {
> resto = numdec % base;
> numbase[i] = DIGITOS[resto];
Aquí está el error. Ten presente que 'numbase' es un puntero, el cual
apunta a una dirección arbitraria de memoria, porque no inicializaste ni
asignaste un valor conocido. Como quieres un array dinámico, tendrás que
crear memoria dinámicamente. Por ejemplo,
numbase = new char[256];
while( numdec >= base )
{
resto = numdec % base;
numbase[i] = DIGITOS[resto];
...
}
El problema de hacer esto es que dejas al programador con la tarea de
liberar la memoria que esta función creó. Desde un punto de vista de
diseño, esto casi nunca es deseable. El típico diseño es aceptar el
array como parámetro a esta función, como has indicado. Esto sería,
char * DectoBase( TIPO1 numdec, TIPO2 base, char *numbase )
{
// ¿Puntero nulo?
if( !numbase ) return 0;
...
return numbase;
}
Con este diseño forzamos al programador pasar el array y hacer las
preparaciones necesarias para que esta función no tenga problemas en su
ejecución. Extendiendo esta idea, también podríamos aceptar otro
parámetro para indicar la cantidad máxima de caracteres que podemos
guardar en esta cadena. Por ejemplo,
char * DectoBase( TIPO1 numdec, TIPO2 base, char *numbase, int nCant )
{
// ¿Puntero nulo o cantidad inexistente?
if( !numbase || nCant<=1 ) return 0;
...
return numbase;
}
Espero haber aclarado la duda.
Steven
Más información sobre la lista de distribución Cconclase