Ошибка забивания памяти - PullRequest
5 голосов
/ 04 июля 2011

У меня есть маленький кусочек кода.Я скомпилировал его с -lmcheck, так как я пытаюсь отладить код, в котором у меня та же самая ошибка.

Я получаю эту ошибку при запуске этого кода:

memory clobbered before allocated block

Может кто-тообъясните причину, по которой free(ptr) выдаст мне эту ошибку?

Как еще можно освободить указатель?

Спасибо.

#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;
}

Ответы [ 4 ]

8 голосов
/ 04 июля 2011

Вы увеличиваете ptr, поэтому меняете адрес, на который он указывает. Вы не можете сделать это.

В вашем случае, используйте отдельный указатель, скажем, char * p = ptr и выполняйте свои операции с p, оставляя ptr без изменений, чтобы вы могли free(ptr) позже.

РЕДАКТИРОВАТЬ Взглянув еще раз на ваш код, я обнаружил, что вы делаете ptr++, когда вы не должны. Вы получаете доступ к символам в массиве, например ptr[i], если вы путаетесь с указателем ptr, вы изменяете базовый адрес, а доступ к символам с помощью ptr[i] может привести (и приведет) к неожиданным результатам.

Если вы просто удалите эту строку (ptr++), ваш код будет работать магическим образом. Если вы хотите изучить концепцию указателя и попробовать другое решение, ваш код может выглядеть примерно так:

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;
}
2 голосов
/ 04 июля 2011

Потому что ptr больше не указывает на базу выделенной памяти.

1 голос
/ 04 июля 2011

Найдите ответ в комментариях.При выделении некоторой памяти, как правило, инфраструктура управления памятью отслеживает ее, добавляя дополнительную информацию (можно сказать, верхний и нижний колонтитулы) в выделенную область памяти.Когда вы освобождаете эту память, сопоставляется та же информация, чтобы обнаружить любой нежелательный / недействительный доступ к памяти.

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;
}
1 голос
/ 04 июля 2011

Кроме того, после увеличения ptr выражение ptr[i] не возвращает ожидаемого; и именно поэтому вывод начинается с «hlo».

...