Недопустимая (прерванная) ошибка дампа ядра при использовании free () в C - PullRequest
1 голос
/ 14 января 2020

вот код: кто-нибудь может объяснить эту проблему, как я могу освободить память s в main

char *get(int N)
{
    char *s=malloc(10*sizeof(char));  
    s="hello";  
    return s;  
}
 int main()  
{  
    char *s=get(4);  
    printf(s);  
    free(s);  
}

Ответы [ 4 ]

6 голосов
/ 14 января 2020

Это здесь:

s="hello";

Не записывает "hello" в выделенную память. Вместо этого он переназначает s, указывая на место только для чтения, где хранится "hello". Память, выделенная с помощью malloc, просочилась, а free(s); недействительна, поскольку вы не можете освободить эту постоянную память.

Если вы хотите скопировать "hello" в s, вместо этого попробуйте strcpy(s,"hello");.

1 голос
/ 14 января 2020

Делая

s="hello";

, вы перезаписываете возвращаемый указатель на malloc() указателем на первый элемент строкового литерала "hello", который не выделяется динамически.

Затем вы передаете этот указатель (строковому литералу) на free(), что вызывает неопределенное поведение.

Возможно, вы захотите изменить присвоение на

strcpy(s, "hello");

Дополнительно перезаписывая первоначально возвращенный указатель на malloc(), у вас нет шансов освободить память - поэтому вы также можете вызвать утечку памяти.

0 голосов
/ 14 января 2020

Переменная типа char * является указателем (адресом памяти) на символ. В C принято реализовывать строки как символьные массивы с нулевым символом в конце и обрабатывать строки, используя переменные типа char * для первого элемента такого массива.

Таким образом, переменные типа char * на самом деле не содержит строк, они просто указывают на них.

По этой причине строка

s="hello";

фактически не копирует содержимое строка, а точнее только указатель (то есть адрес памяти) строки.

Если вы хотите скопировать фактическое содержимое строки, вы должны использовать вместо нее функцию strcpy .

Перезаписывая указатель, который вы используете для хранения адреса памяти, выделенной malloc, вы вместо этого передаете адрес строкового литерала "hello" в free. Это не должно быть сделано. Вместо этого вы должны только передавать адреса памяти free, которые вы получили от malloc.

0 голосов
/ 14 января 2020

У вас есть две ошибки:

  1. Вы переназначаете указатель s со ссылкой на строковый литерал "hello", теряя память, выделенную на malloc

  2. Вы выделяете недостаточно места для строки "привет". Вам нужно как минимум 6 символов (не 4)

...