[C con Clase] Segmentation fault al ejecutar la sentencia free() en una función

Emilio Manzaneque emanzaneque en orange.es
Dom Nov 2 13:06:14 CET 2014


Hola,

 

Retiro lo dicho, no funciona…

 

En el momento de retornar a “main” se pierde el valor de retorno.

 

Sí que funciona, como al principio, así:

 

char *inserta(char* mensaje, char* cadena, int posicion)

{

      char *salida = NULL;

      int lcadena, lmensaje;

      

      lmensaje = longitud(mensaje);

      lcadena = longitud(cadena);

      

      salida = (char*) malloc(lmensaje+lcadena+1);

      

                                                   

      //copia la parte de la cadena antes de la posición de inserción

                  memcpy(salida,mensaje,posicion);

                  salida+=posicion;

                  mensaje+=posicion;

 

      //inserta la cadena en este punto

      memcpy(salida,cadena,lcadena);

      salida+=lcadena;

 

      //acaba de completa la cadena de salida con el resto del mensaje

      memcpy(salida,mensaje,(lmensaje-posicion));

      salida+=(lmensaje-posicion);

      *salida = 0x00;

      salida-=(lmensaje+lcadena);

 

      return salida;

}

 

Pero claro, entiendo que cada vez que ejecute la función ocuparé una nueva posición de memoria…

 

Saludos

 

 

De: Emilio Manzaneque [mailto:emanzaneque en orange.es] 
Enviado el: domingo, 02 de noviembre de 2014 11:56
Para: 'Lista de correo sobre C y C++'
Asunto: RE: [C con Clase] Segmentation fault al ejecutar la sentencia free() en una función

 

Hola,

 

Antes de nada volver a agradecer a Salvador Pozo y a marcelinux su ayuda.

 

Al final he llegado a un resultado que funciona:

 

char *inserta(char* mensaje, char* cadena, int posicion)

{

      char *salida = NULL;

      int lcadena, lmensaje;

      

      lmensaje = longitud(mensaje);

      lcadena = longitud(cadena);

      

      char retorno[lmensaje+lcadena+1];

      

      salida = (char*) malloc(lmensaje+lcadena+1);

      

                                                   

      //copia la parte de la cadena antes de la posición de inserción

                  memcpy(salida,mensaje,posicion);

                  salida+=posicion;

                  mensaje+=posicion;

 

      //inserta la cadena en este punto

  memcpy(salida,cadena,lcadena);

  salida+=lcadena;

 

      //acaba de completa la cadena de salida con el resto del mensaje

                memcpy(salida,mensaje,(lmensaje-posicion));

                salida+=(lmensaje-posicion);

                *salida = 0x00;

                salida-=(lmensaje+lcadena);

 

//En este punto copio la cadena entera sobre la variable array “retorno” para poder liberar la memoria utilizada por la variable “salida”

memcpy(retorno,salida,(lmensaje+lcadena+1));

                free(salida);

                return retorno;

}

 

Entendiendo que la memoria que ocupa la variable array retorno se liberará, al igual que las demás variables definidas en este bloque, al salir de la función.

 

No me parece quizás una solución muy elegante, por lo que si se os ocurre como mejorarla estaría muy agradecido.

 

La idea que persigo es la de utilizar el mínimo de librerías posibles y por tanto hacer un código lo más compacto y eficiente posible.

 

Otra cosa de la que me he dado cuenta es que memcpy no mueve bloques de memoria si no que, por lo que entiendo del siguiente código, lo hace byte a byte, o al menos tal como implementa esta función DEV-C++ 5.7.0.

 

   0x76dd9d70 <+130>:  mov    al,BYTE PTR [esi]

=> 0x76dd9d72 <+132>:mov    BYTE PTR [edi],al

   0x76dd9d74 <+134>:  mov    al,BYTE PTR [esi+0x1]

   0x76dd9d77 <+137>:  shr    ecx,0x2

   0x76dd9d7a <+140>:  mov    BYTE PTR [edi+0x1],al

   0x76dd9d7d <+143>:  add    esi,0x2

   0x76dd9d80 <+146>:  add    edi,0x2

   0x76dd9d83 <+149>:  cmp    ecx,0x8

   0x76dd9d86 <+152>:  jb     0x76dd9957 <msvcrt!memcpy+71>

 

En cualquier caso mi assembler está más que oxidado por lo que digo esto con todas las reservas.

 

Gracias de nuevo por la ayuda.

 

------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20141102/e496749e/attachment.html>


Más información sobre la lista de distribución Cconclase