[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