Free () возвращает указатель на символ, не удаляет его из памяти? - PullRequest
1 голос
/ 27 октября 2010

В основном проблема сводится к следующему:

Я загружаю файл, записываю все символы в переменную char *, которая имеет malloc () длину файла.Затем я возвращаю эту переменную и печатаю ее, затем освобождаю () память для этой переменной и пытаюсь снова напечатать переменную, которая ее печатает.

Я очень плохо знаком с C, так что, вероятно, что-то не так в том, как я обрабатываю память для переменной, содержащей текстовое содержимое.

Я пытался использовать char [(ftell (file)] вместо malloc и char *, но затем функция ничего не возвращала. Вероятно, это потому, что это локальная переменная, которая освобождается, когда функция возвращает,да?

Вот как выглядит мой код:

main.c:

#include <stdio.h>
#include <stdlib.h>
#include "data/filesystem/files.h"

int main(){
    char *filebuffer = retrieve_file_content("assets/test.txt");
    printf("%s", filebuffer);
    free(filebuffer);
    printf("%s", filebuffer);
    return 0;
 }

files.c:

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

char *retrieve_file_content(char* path){
    FILE *file;
    file = fopen(path, "r");
    if(file){
        fseek(file, 0L, SEEK_END);
        char *filebuffer = malloc(ftell(file));
        if(filebuffer == NULL){ return NULL; }
        fseek(file, 0L, SEEK_SET);
        int i = 0;
        int buffer = getc(file);
        while(buffer != EOF){
            filebuffer[i] = buffer;
            buffer = getc(file);
            i++;
        }
        fclose(file);
        return filebuffer;
    }else{
        return NULL;
    }
}

test.txt:

heheasdasdas

вывод:

heheasdasdas
heheasdasdas

Заранее спасибо!

Ответы [ 3 ]

10 голосов
/ 27 октября 2010

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

3 голосов
/ 27 октября 2010

То, что вы наблюдаете, является неопределенным поведением.Это работает для вас в этот раз, может произойти сбой в следующий раз.Не делайте этого.

После вызова free() владение блоком памяти передается среде выполнения C, а данные, хранящиеся в блоке, не изменяются (последнее делается из соображений производительности).Бывает, что блок по-прежнему отображается в памяти процесса, поэтому для вас это выглядит так, как будто вы можете безопасно его прочитать.Однако, в зависимости от нескольких условий, это может привести к сбою программы, чтению измененных данных или к любым другим последствиям.Никогда не пытайтесь получить доступ к памяти, которую вы уже free() d.

1 голос
/ 27 октября 2010

Поведение вашей программы не определено: стандарт C ничего не говорит о том, что происходит с памятью после вызова free, только то, что вы больше не должны ее использовать.Большинство реализаций помещают его обратно в свободный список, так что следующий вызов malloc может использовать его.Некоторые возвращают его в операционную систему, но только реализации C для небольших компьютеров могут это сделать.Некоторые могут стереть это, но это могут сделать только реализации с высоким уровнем безопасности.

Т.е. поведение вашей программы зависит исключительно от совпадений и может не сработать завтра / в день года / когда луна полна.

...