Память затерта

Я озадачен этим ответом. Может ли кто-нибудь помочь мне в этом и указать, где я делаю ошибку? Вывод на кодовой панели "memory clobbered before allocated block"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char *s = (char *)malloc(10 * sizeof(char));
    s = "heel";
    printf("%s\n",s);
    printf("%c\n",s[2]);
    printf("%p\n",s);
    printf("%d\n",s);
    free(s);
    return 0;
}

person kevin    schedule 26.12.2011    source источник
comment
stackoverflow.com/questions/6571455/memory-clobbering-error   -  person Robert Harvey    schedule 27.12.2011


Ответы (4)


Вы пытаетесь освободить постоянную память с помощью:

free(s); // cannot free constant "heel"

Что вы делаете, так это выделяете часть памяти и сохраняете ее местоположение (char *s). Затем вы перезаписываете эту ссылку на строковую константу "heel" (утечка памяти), которая не может быть freed. Чтобы заставить это вести себя так, как хотелось бы, вы должны скопировать константную строку в выделенную вами память:

strcpy(s, "heel");

Вот пример получения пользовательского ввода:

char *input = malloc(sizeof(char) * 16); // enough space for 15 characters + '\0'
fgets(input, 16, stdin);

// do something with input

free(input);
person Tim Cooper    schedule 26.12.2011
comment
Спасибо, Тим. Итак, что означает использование malloc для инициализации памяти, а s = heel — это две разные вещи? s=heel автоматически инициализирует память? - person kevin; 27.12.2011
comment
@kevin: когда ваша программа запускается, строковая константа heel сохраняется в памяти и доступна только для чтения; s = "heel" присваивает s местонахождению этой доступной только для чтения строки. Поэтому при попытке free(s) вы получите сообщение об ошибке. - person Tim Cooper; 27.12.2011
comment
так что произойдет, если я захочу ввести строку с клавиатуры и освободить память после того, как закончу с ней? - person kevin; 27.12.2011

Нельзя free(s) - это постоянная память.

Попробуйте заменить s = "heel"; на strcpy(s,"heel");

person SlavaNov    schedule 26.12.2011

Чтобы расширить ответ @TimCooper:

  • сначала вы делаете: char *s = (char *)malloc(10 * sizeof(char));
  • затем: s = "heel";

Первая строка выделяет память и назначает расположение этой памяти s. Но вторая строка переназначает s на ячейку памяти константной строки heel в стеке!

Это означает, что вы пытаетесь использовать память free() в стеке, что является незаконным. И у вас происходит утечка памяти, поскольку то, что вы сначала выделили для s, теперь недоступно.

Если вы хотите записать строку в память, на которую указывает s, вы должны использовать что-то вроде strcpy() (или, лучше, strncpy()).

person fge    schedule 26.12.2011

char *s = (char *)malloc(10 * sizeof(char));
  s = "heel";

Делает не то, что вы думаете, или то, что вы ожидаете от более современных языков.

Первая строка выделяет память для 10 символов и возвращает ее адрес.

Вторая строка изменяет этот адрес, чтобы он указывал на постоянный блок памяти, выделенный во время компиляции, содержащий «пятку», теряющую ссылку на выделенную память — утечку.

person Martin Beckett    schedule 26.12.2011