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

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Mejor forma de procesar una cadena de formato [Cantidad de memoria]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Mejor forma de procesar una cadena de formato [Cantidad de memoria]  (Leído 2,584 veces)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Mejor forma de procesar una cadena de formato [Cantidad de memoria]
« en: 16 Septiembre 2016, 00:12 am »

Buenas!!

Estoy haciendo un pequeño servidor WEB en C, algo basico y como ejercicio, ya que este algo pulido dejare el link al codigo por aqui.


El detalle que me encuentro es que quiero crear una función de argumentos variables asi como el printf donde le ahorre al usuario "final" ( :rolleyes: :rolleyes:) el reservar memoria para el buffer de respuesta al cliente. para ello solo creare una función llamada "server_print" donde el usuario colocara su formato de cadena y las variables que el quiera. Y que la función haga el trabajo duro...

session es un contenedor de variables auxiliares y ese de momento, se puede obviar...

Código
  1. void server_print(struct peticion *session,char *format,...) {
  2. char *buffer = NULL;
  3. int X;
  4. va_list args;
  5. va_start(args, format);
  6. buffer =malloc(X);
  7. vsnprintf(buffer,X,format, args);
  8.  
  9. //realizar operaciones sobre session...
  10.  
  11.  
  12. va_end(args);
  13. }
  14.  

Lo que me interesa saber es el cuando debe de valer X para reservar esa cantidad de memoria exacta.. el detalles esta en que puedo ahórrame el "pensar" y asignar MUCHA memoria por cada argumento del programa, pero el detalle esta en que:

¿Que pasa si no alcanza?

Quiero tener un programa eficiente que no malgaste memoria y sea rápido...

Se me ocurre buscar en la cadena de formato por cada % que se encuentre y por ejemplo si es un Entero reservar solo 12 bytes mas, si es cadena sacar el strlen del argumento en cuestion, si es %l dejar sobre 30 bytes mas y asi...

¿Como procederían ustedes?

Saludos!


En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Mejor forma de procesar una cadena de formato [Cantidad de memoria]
« Respuesta #1 en: 16 Septiembre 2016, 00:54 am »

Si tienes que guardarlo todo (no puedes procesar iterativamente sobre cada argumento) puedes crear una estructura así:
Código:
struct argumento {
    int tipo;
    void *valor;
};

Donde tipo es un entero que indicará de qué tipo fundamental es el argumento, podrías generar una lista con un enum para más comodidad.
En valor, mediante malloc, reservas tanta memoria como sea necesaria, según tipo y tamaño (en caso de cadena).

Al procesar tu cadena cuentas cuántos % hay en tu cadena y no sean %%, funcionamiento típico de printf, y mediante malloc generas un array dinámico de tantas estructuras argumento.
Creado el array iteras sobre los argumentos y vas rellenando el array.

A la hora de leerlo solo debes ir fijándote sobre que tipo es el elemento del array y hacer el cast correspondiente a su tipo a la hora de recuperar el valor.


En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Mejor forma de procesar una cadena de formato [Cantidad de memoria]
« Respuesta #2 en: 16 Septiembre 2016, 14:23 pm »

Muchas gracias MAFUS segui mas o menos tu consejo y quedo asi el codigo:

Código
  1. void server_print(struct peticion *session,char *format,...) {
  2. int len = 0,count = 0,i,X;
  3. char *buffer = NULL;
  4. struct m_args *arreglo = NULL;
  5. va_list args;
  6. va_start(args, format);
  7. len = strlen(format);
  8. X = len;
  9. i = 0;
  10. while(i < len) {
  11. if(format[i] == '%') {
  12. i++;
  13. printf("Evaluando %c\n",format[i]);
  14. switch(format[i]) {
  15. case 's':
  16. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  17. arreglo[count].valor = va_arg(args, void *);
  18. X+= strlen((char*)arreglo[count].valor);
  19. count++;
  20. break;
  21. case 'i':
  22. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  23. arreglo[count].valor = va_arg(args, void *);
  24. X+=11;
  25. count++;
  26. break;
  27. case 'u':
  28. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  29. arreglo[count].valor = va_arg(args, void *);
  30. X+=11;
  31. count++;
  32. break;
  33. case 'd':
  34. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  35. arreglo[count].valor = va_arg(args, void *);
  36. X+=11;
  37. count++;
  38. break;
  39. case 'f':
  40. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  41. arreglo[count].valor = va_arg(args, void *);
  42. X+=11;
  43. count++;
  44. break;
  45. case 'x':
  46. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  47. arreglo[count].valor = va_arg(args, void *);
  48. X+=11;
  49. count++;
  50. break;
  51. case 'l':
  52. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  53. arreglo[count].valor = va_arg(args, void *);
  54. X+=20;
  55. count++;
  56. break;
  57. case 'c':
  58. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  59. arreglo[count].valor = va_arg(args, void *);
  60. X+=1;
  61. count++;
  62. break;
  63. case '%':
  64. X+=1;
  65. break;
  66. default:
  67. arreglo = realloc(arreglo,sizeof(struct m_args)*(count+1));
  68. arreglo[count].valor = va_arg(args, void *);
  69. X+=20;
  70. count++;
  71. break;
  72. }
  73. }
  74. i++;
  75. }
  76. free(arreglo);
  77. va_end(args);
  78. buffer = malloc(X+1);
  79. va_start(args, format);
  80. vsnprintf(buffer,X,format, args);
  81. va_end(args);
  82. buffer[X] = 0;
  83. len = strlen(buffer);
  84. printf("Longitud reservada %i vs Real %i\n",X,len);
  85. X = session->reply_length + len;
  86. session->reply = realloc(session->reply,X+1);
  87. memcpy(session->reply+ session->reply_length,buffer,len);
  88. session->reply[X] = 0;
  89. session->reply_length = X;
  90. free(buffer);
  91. }
  92.  

Resulta que podria llamar varias veces a va_start(args, format); y va_end...

Y asi solo itere sobre los argumentos viendo su tipo (Segun el formato de Cadena) reserve la memoria mas o menos necesitada por el tipo y volvi a llamar a va_start para posteriormente hacer un vsnprintf

Código
  1. vsnprintf(buffer,X,format, args);

Aun asi me faltan los formatos mas especializados pero eso con tiempo lo voy hacer, puse un default de +20 bytes por parametro "desconocido"



Saldos!
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Mejor forma de procesar una cadena de formato [Cantidad de memoria]
« Respuesta #3 en: 16 Septiembre 2016, 22:31 pm »

Utiliza los datos que te da la propia función. La función retorna la cantidad de caracteres que necesita.

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4.  
  5.  
  6. void temp(char* format, ...){
  7. va_list list;
  8.  
  9. va_start(list, format);
  10. int n = vsnprintf(0, 0, format, list);
  11. va_end(list);
  12.  
  13. char* t = malloc(n+1);
  14.  
  15. va_start(list, format);
  16. vsnprintf(t, n+1, format, list);
  17. va_end(list);
  18.  
  19. printf("%s", t);
  20. fflush(stdout);
  21. }
  22.  
  23. int main(){
  24. temp("%i%i%i", 123,456,789);
  25. }
En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Mejor forma de procesar una cadena de formato [Cantidad de memoria]
« Respuesta #4 en: 18 Septiembre 2016, 02:30 am »

Eso me pasa por no leer la documentacion de la funcion  ;D  ;-) ;-) ;-)

Ya quedo mas optimizada mi funcion, muchas gracias  :xD
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Motorola RAZR Stack Overflow al procesar imágenes con formato JPG
Hacking Mobile
ANELKAOS 2 3,616 Último mensaje 8 Julio 2008, 03:45 am
por putus
Vulnerabilidad de cadena de formato
Hacking
Z31C0S 0 2,578 Último mensaje 20 Diciembre 2011, 23:16 pm
por Z31C0S
Cantidad de caracteres en un arreglo y cortar una cadena
Programación C/C++
josri 5 3,869 Último mensaje 16 Marzo 2013, 16:34 pm
por naderST
¿Qué cantidad de memoria RAM es la adecuada para mi ordenador?
Noticias
wolfbcn 0 1,275 Último mensaje 13 Abril 2014, 21:37 pm
por wolfbcn
Mostrar la cantidad de veces que una cadena se repite
Programación C/C++
andoporto 1 2,749 Último mensaje 9 Febrero 2015, 08:10 am
por eferion
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines