elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  bug en mi codigo
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: bug en mi codigo  (Leído 1,820 veces)
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
bug en mi codigo
« en: 9 Junio 2014, 22:52 pm »

Saludos

tengo la siguiente función que se llama checkSumS1() que creo que me esta ocasionando que me truene un programa, no quiero publicar el código completo porque son 3,500 y tantas líneas de código. Lo que hace es que le paso 3 cadenas(Longitud, direccion y codigo_datos) y dentro de la función las concatena en una variable llamada registroS1, después va leyendo registroS1 de dos caracteres en dos. Por ejemplo si tengo ABE31000 primero va a obtener AB, que se supone es un "numero hexadecimal" y lo voy a convertir a su equivalente en decimal, y lo mismo con los demas caracteres. los decimales se van sumando, a la suma se le saca complemento a 1 y se obtienen sus 2 ultimos caracteres

Código
  1. char *CheckSumS1(char *Longitud,char *direccion,char *codigo_datos)
  2. {
  3.    int i,j,k,numero,x = 0,base = 16,suma = 0,complemento;
  4.    char *registroS1,*byte,digito[2],*checksum;
  5.    registroS1 = (char*)malloc(39*sizeof(char));
  6.    checksum = (char*)malloc(3*sizeof(char));
  7.    sprintf(registroS1,"%s%s%s",Longitud,direccion,codigo_datos);
  8.    for(i = 0;registroS1[i];i+=2)
  9.    {
  10.        byte = (char*)calloc(3,sizeof(char));
  11.        for(j = 1,k = i;j <= 2;j++,k++)
  12.        {
  13.            sprintf(digito,"%c",registroS1[k]);
  14.            strcat(byte,digito);
  15.        }
  16.        numero = obtenerNumero(byte,x,base);
  17.        suma+=numero;
  18.        free(byte);
  19.    }
  20.    complemento = ~suma;
  21.    sprintf(checksum,"%02X",complemento);
  22.    checksum = ultimos2bits(checksum);
  23.    return checksum;
  24. }

no se bien cual podria ser la causa de que cada vez que cuando el  codigo llega a esta función para ejecutarla a veces me truena y otras no. no se si  el sprintf y el strcat sean la mejor opcion para usarlos en la función, pero fue lo único que se me ocurrió para que me fuera leyendo de 2 en dos. si alguien me dijera cual es el bug que tiene me codigo se lo agradeceria mucho

gracias


« Última modificación: 9 Junio 2014, 22:54 pm por m@o_614 » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: bug en mi codigo
« Respuesta #1 en: 9 Junio 2014, 23:11 pm »

* registroS1 no es necesario que lo crees con memoria dinámica... o al menos, si lo usas con reserva de memoria, que sea para reservar un buffer lo más pequeño posible:

Código
  1. registroS1 = malloc( strlen(Longitud) + strlen(direccion) + strlen(codigo_datos) + 1 );

* digito es un char... no necesitas crear un buffer para ello:

Código
  1. char digito;
  2.  
  3. // ...
  4.  
  5. digito = registroS1[ k ];
  6.  
  7. byte[ j - 1 ] = digito;

* Dado que byte siempre tiene longitud 3 no tiene tampoco mucho sentido que uses memoria dinámica. Si quieres resetear la memoria basta con que uses, por ejemplo, memset:

Código
  1. char byte[ 3 ];
  2. memset( byte, 0, 3 );

* Dado el bucle "for"... j, perfectamente podría ir de 0 a 2, así lo puedes usar de índice para escribir en "byte"

* Estás seguro que la suma de complemento siempre es inferior a 0xFF??? si no es así tienes un desbordamiento de buffer al almacenar el valor en "checksum".


En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: bug en mi codigo
« Respuesta #2 en: 10 Junio 2014, 18:35 pm »

gracias eferion por tu respuesta, le haré esos cambios a mi código. Una última pregunta, si tengo declarada un puntero como *cadena y después le asigno memoria así:

codigo_datos = (char*)malloc(33*sizeof(char));

es correcto después de hacer esto inicializarla con NULL??

En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: bug en mi codigo
« Respuesta #3 en: 10 Junio 2014, 21:16 pm »

Si haces:

Código
  1. codigo_datos = (char*)malloc(33*sizeof(char));
  2. codigo_datos = 0;

Estás haciendo que el puntero apunte a otra dirección de memoria, por lo que pierdes la dirección de la memoria reservada y eso resulta en una laguna de memoria.

En cambio, si haces:

Código
  1. codigo_datos = (char*)malloc(33*sizeof(char));
  2. *codigo_datos = 0;

Entonces haces que la primera posición de la memoria reservada valga 0, es decir, contiene una cadena de longitud 0.

Aún así, si lo que quieres es que tener la memoria inicializada al reservarla, puedes usar calloc en vez de malloc. calloc inicializa la memoria, poniendo todos los bytes a 0:

Código
  1. codigo_datos = (char*)calloc(33, sizeof(char));
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: bug en mi codigo
« Respuesta #4 en: 11 Junio 2014, 03:37 am »

no se bien cual podria ser la causa de que cada vez que cuando el  codigo llega a esta función para ejecutarla a veces me truena y otras no.
En mi opinión la causa mas probable es la indicada por eferion, otro escenario donde la función puede reventar se da si el total de caracteres a procesar es impar, en ese caso el bucle principal eventualmente procesara el carácter siguiente al '\0'.

no se si  el sprintf y el strcat sean la mejor opcion para usarlos en la función
Con todo respeto no son, ni de lejos, las mejores opciones. Eso ya lo había comentado en varios de tus temas.

Para el caso es mejor utilizar aritmética de punteros y sscanf para leer cada uno de los bytes (base 16, dos dígitos). Un ejemplo sin las validaciones recomendadas (de malloc y sscanf):
Código
  1. unsigned char chk(char *lon, char *dir, char *cod)
  2. {
  3.   size_t nb = strlen(lon) + strlen(dir) + strlen(cod);
  4.   size_t i;
  5.  
  6.   char *p = malloc(nb + 1);
  7.   unsigned total = 0;
  8.   unsigned byte;
  9.  
  10.   sprintf(p, "%s%s%s", lon, dir, cod);
  11.   for (i = 0; i < nb; i += 2){
  12.      sscanf(p + i, "%2x", &byte);
  13.      total += byte;
  14.   }
  15.  
  16.   return ~total & 0xFF;
  17. }
El tipo de retorno es unsigned char para evitar la reserva de memoria.

Tal vez se pueda mejorar pero ello depende de cierta información que no provees, por ejemplo si el numero de caracteres de cada cadena esta garantizado a ser par se puede evitar la reserva de memoria (mediante malloc) y en su lugar utilizar un array de punteros y dos bucles anidados.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: bug en mi codigo
« Respuesta #5 en: 11 Junio 2014, 19:19 pm »

muchas gracias por sus respuestas, si el  número de caracteres de la cadena tiene que ser a fuerzas par, porque los voy leyendo de dos en dos
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines