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

Emilio Manzaneque emanzaneque en orange.es
Mie Oct 29 18:02:03 CET 2014


Hola,

 

Antes de nada muchas gracias por tu rápida y precisa respuesta.

 

La verdad es que la forma que me sugerías es mucho mejor y he cambiado la estructura para adecuarla a tus indicaciones:

 

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

{

      char *salida = NULL;

      int lcadena, lmensaje;

      char paso;

 

      salida = (char*) malloc(512);

      lmensaje = longitud(mensaje);

                                                   

      //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

      lcadena = longitud(cadena);

      memcpy(salida,cadena,lcadena);

      salida+=lcadena;

 

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

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

      salida+=(lmensaje-posicion);

      *salida = 0x00;

      salida -= (lcadena+lmensaje);

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

                  free(salida);

      return cadena;

}

 

El caso es que me sigue pasando, he comprobado que cuando creo el puntero salida tiene la dirección de memoria 0x8d10c8 y justo antes de ejecutar free(salida) tiene exactamente la misma dirección.

 

¿Cómo me sugieres que haga la copia del puntero que me indicabas?...

 

Gracias de nuevo.

 

 

De: Cconclase [mailto:cconclase-bounces en listas.conclase.net] En nombre de Salvador Pozo
Enviado el: miércoles, 29 de octubre de 2014 12:29
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:

El programa aparentemente está bien. No he podido probarlo porque no dispongo de la implementación de la función "longitud", pero he usado la función estándar "strlen", y no se producen errores.

Esto me lleva a pensar que, con toda probabilidad, el error está en la función "longitud", que debe calcular mal la longitud de la cadena. Este error hace que el valor calculado de "salida" justo antes del "free" no esa exactamente el original, y el "segmentation fault" se produce al intentar liberar memoria en una dirección incorrecta.

Además de esto, me gustaría comentar algunas cosas.

1) Con respecto a la función memcpy, decir que esta función está optimizada para copiar bloques de memoria. Hasta tal punto puede ser así que, probablemente, sólo se usa una instrucción de código máquina para ese copiado, de modo que usarla en un bucle para copiar datos de direcciones consecutivas es bastante ineficaz.

En lugar de esto:

      for (int i = 0; i < posicion; i++)

      {

          memcpy(salida,mensaje,1);

          salida++;

          mensaje++;

      }

Es mucho mejor usar esto:

memcpy(salida,mensaje,posicion);

salida+=posicion;

mensaje+=posicion;

 

2) De hecho, para copiar cadenas es mejor usar strcpy, o en tu caso, strncpy. Esta segunda permite indicar el número máximo de caracteres a copiar.

3) Para evitar cuentas al final, a la hora de liberar memoria, tal vez sería más interesante guardar una copia del puntero "salida". Esto nos asegura que no perdemos su valor, aunque alguna de las cuentas esté mal o haya algún error no previsto.

Hasta pronto.
-- 

Salvador Pozo Coronado
http://www.conclase.net
Blog con Clase: http://blogconclase.wordpress.com
mailto:salvapozo en gmail.com





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


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