2011-07-04 11 views
5

Tengo un pequeño fragmento de código. Lo compilé con -lmcheck ya que estoy intentando depurar un código donde tengo el mismo error similar.Error de recuperación de memoria

consigo este error al ejecutar este código:

memory clobbered before allocated block 

Puede alguien explicar la razón por la free(ptr) me va a lanzar este error?

¿De qué otra forma puedo liberar el puntero?

Gracias.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#define LEN 5 


int main(int argc, char *argv[]){ 

    char *ptr = NULL; 

    ptr = (char *) malloc(LEN+1);// +1 for string 
    strcpy(ptr, "hello"); 

    int i = 0; 
    for(i = 0; i<LEN; i++) 
    { 
     printf("ptr[%d] = %c\n", i, ptr[i]); 
     ptr++; 
    } 
    free(ptr); 


    return 0; 
} 
+0

Además, considere http://stackoverflow.com/questions/605845/doi-i-cast-the-result-of-malloc/605858#605858. – unwind

Respuesta

8

Usted está incrementando ptr, por lo tanto, el cambio de la dirección que apunta. No puedes hacer eso.

En su caso, tienen un puntero separada, digamos char * p = ptr y hacer sus operaciones con p dejando intacta ptr para que pueda free(ptr) más tarde.

EDIT Echando un segundo vistazo a su código, encontré que está haciendo ptr++ cuando no debería. Está accediendo a los caracteres en la matriz como ptr[i], si se entromete con el puntero ptr, está cambiando la dirección base y acceder a los caracteres con ptr[i] puede conducir (y conducirá) a resultados inesperados.

Si simplemente elimina esa línea (ptr++) su código funcionará mágicamente. Si desea explorar el concepto de puntero e intentar otra solución, el código podría ser algo como esto:

int main(int argc, char *argv[]){ 

    char *ptr = NULL; 
    char * p; 

    ptr = (char *) malloc(LEN+1);// +1 for string (please check for NULL) 
    p = ptr; 

    strcpy(ptr, "hello"); 

    int i = 0; 
    while (*p) // note how I changed it to a while loop, C strings are NULL terminated, so this will break once we get to the end of the string. What we gain is that this will work for ANY string size. 
    { 
     printf("ptr[%d] = %c\n", i++, *p); // here i dereference the pointer, accessing its individual char 
     p++; 
    } 
    free(ptr); 


    return 0; 
} 
+1

Excelente explicación! Gracias por hacer un esfuerzo adicional. –

2

Debido ptr puntos ya no a la base de la memoria que asigna.

1

Además, después de incrementar ptr, la expresión ptr[i] no devuelve lo que cabría esperar; y es por eso que la salida comienza con "hlo".

1

Encuentra la respuesta en los comentarios. Cuando asigna parte de la memoria, normalmente, el marco de administración de memoria mantiene un registro de la misma agregando más información (puede decir Encabezado y pie de página) al área de memoria asignada. Cuando libera esta memoria, la misma información coincide para detectar cualquier acceso de memoria no deseado/no válido.

int main(int argc, char *argv[]){ 

    char *ptr = NULL; 
    char* temp = NULL;   // Have a temp pointer. 

    ptr = (char *) malloc(LEN+1);// +1 for string 
    strcpy(ptr, "hello"); 

    temp = ptr;     // manipulate temp pointer instead of ptr itself 

    int i = 0; 
    for(i = 0; i<LEN; i++) 
    { 
     printf("ptr[%d] = %c\n", i, temp[i]); 
     temp++;     // Why you are incrementing this? Just to print, there is no need of this. 
    } 
    free(ptr); 


    return 0; 
} 
Cuestiones relacionadas