Когда я должен использовать free () в C?

код работает так, как он должен, хотя он никогда не освобождает память, выделенную malloc().

Я пытался освободить память в любом месте, где я могу, но независимо от того, где я это делаю, это нарушает программу. В частности, я получаю "двойную бесплатную или коррупционную ошибку".- Это скорее вопрос о том, что ... --2--> и malloc() на самом деле делать? Все проблемы с free в основном:

int main(int argc,  char *argv[]){
if(argc!=2){
    exit(1);
}

printf("CSA WC version 1.0nn");

int length = strlen(argv[argc-1]);
char file_to_open[length];
strcpy(file_to_open, argv[argc-1]);

//printf("filename:%sn",file_to_open);

//create counters for output
int count_number_of_lines = 0;
int count_number_of_words = 0;
int count_number_of_characters = 0;

//create int size of default array size
int current_array_size = pre_read(file_to_open);
//printf("number of lines: %in",current_array_size);

//create string array of default size
char *strings_array[current_array_size];

//create a pointer to catch incoming strings
char *incoming_string=NULL;

int done=0;
while(done==0){
    incoming_string=get_line_from_file(file_to_open, count_number_of_lines);
    if(incoming_string!=NULL){
        incoming_string=csestrcpy2(incoming_string);
        //printf("incoming line: %sn",incoming_string);
        strings_array[count_number_of_lines]=(char*)malloc(strlen(incoming_string+1));
        strings_array[count_number_of_lines]=csestrcpy2(incoming_string);
        //printf("added to array:%sn",strings_array[count_number_of_lines]);
        count_number_of_lines++;
        count_number_of_characters=(count_number_of_characters+(strlen(incoming_string)-1));
    }
    else{
        done=1;
    }

}
//all data is stored in a properly sized array


//count all words in array
int count=0;
int word_count=0;
char *readline;

while(count<current_array_size){
    readline = csestrcpy2(strings_array[count]);
    printf("line being checked: %s", readline);

    int i=0;
    int j=1;

    while( j< strlen(readline)+1 ){
        if(strcmp(readline,"n")!=0){
            if( (readline[i] == ' ') && (readline[j] != ' ') ){
                word_count++;
            }
            if( (readline[i] != ' ') && (readline[j] == 'n') ){
                word_count++;
            }
        }
        i++;
        j++;
    }
    count++;
}
printf("current word count: %i", word_count);
return 0;
}



char* csestrcpy2(char* src){

int i = 0;
char *dest;
char t;
dest = (char*) malloc(MAX_LINE);

while( src[i] != ''){

    dest[i] = src[i];
    i++;

}

dest[i] = '';
//printf("length:%in",i);
free(dest);

return dest;
}

7 ответов


В общем вам нужно только высвободить память, которая была зарезервирована для вас динамично. Это означает, что если у вас есть такое утверждение:

int *my_int_pointer;
my_int_pointer = malloc(sizeof(int));

чем вам нужно освободить память, которая была выделена (зарезервирована) malloc. если вы не знаете, где его освободить, чем просто освободить его в конце программы, используя free;

free(my_int_pointer);

в вашем файле похоже, что будет выделена память всякий раз, когда есть новая строка в файле, который Вы читаете (в while(done==0) петли). так каждый раз после if в этом цикле вы должны освободить память, которая использовалась переменной.

кроме того, вам нужно освободить память, которая была выделена для переменной readline. Но, как было указано ранее, у вас может быть утечка памяти.

надеюсь, что это помогает.

edit: хорошо-я уже задавался вопросом о '){ dest[i] = src[i]; i++; } dest[i] = ''; //printf("length:%i\n",i); free(dest); /* This frees the memory, but you return a pointer */ return dest; /* to this memory. this is invalid. */ }

что же ты можешь бесплатно КГД указатель в этой функции. но помните: указатель не может содержать информацию после освобождения базовой памяти! Он просто указывает на место в памяти, где он больше не должен писать или читать.

кроме того, функция копирует строку, пока нет '\0'. Что произойдет, если Терминатора не будет? Функция продолжает копировать из некоторых адресов памяти, где она не должна!

вы не должны использовать эту функцию ;)


должен быть вызов free() для каждого успешного вызова malloc().

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

(вы можете почти наверняка уйти с не free()ing выделенная память, когда ваша программа завершается, так как она будет восстановлена операционной системой, но как вопрос стиля и хорошей практики вы все равно должны соответствовать malloc()С free()s.)

я игнорирую calloc() и realloc() звонки.


Dynamic memory allocation (malloc) выделяет блок памяти запрошенного размера и возвращает указатель на начало этого блока.Поскольку мы взяли этот блок из памяти, поэтому его хорошая практика, чтобы вернуть это обратно в память после завершения задачи.

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

main{
    int *i;
    ..
    ..
    i=(int *)malloc(sizeof(int));
    ...//so something with i
    ..
    free(i);
    return 0;
}

как правило, для каждого malloc должно быть соответствующее free. Однако нельзя free что-то дважды (как вы заметили сейчас). Я не вижу никаких звонков free в коде, так что невозможно сказать, где ваша проблема, но я сразу заметил, что вы malloc память и присвоить его readline внутри цикла, но вы не вызываете free on readline в конце цикла, так что вы не утечка памяти есть.


думать malloc и free как "начало" и "конец". Каждый раз, когда вы звоните malloc, делать то, что вам нужно, и как только вы закончите, всегда называю free. Убедитесь, что только освободить его один раз, double-free является ошибкой времени выполнения.

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

для повторной итерации: освободите все, что возвращает malloc (кроме null).


эта строка:

strings_array[count_number_of_lines]=(char*)malloc(strlen(incoming_string+1));

переопределяется строкой рядом с ним, поэтому его можно удалить.

вы также должны добавить free(readline) после count++ в последнем цикле, чтобы освободить память, созданную malloc.


        i++;
        j++;
        /// free here
        free(readline);
    }
    count++;

}
printf("current word count: %i", word_count);

//free here as well
for(int k = 0; k < count_number_of_lines; k++)
{
    free(strings_array[count_number_of_lines]);
}

return 0;
}

Это должно работать.

В общем - любая память, выделенная динамически-используя calloc/malloc / realloc, должна быть освобождена с помощью free (), прежде чем указатель выйдет из области видимости.

Если вы выделяете память с помощью "new", вам нужно освободить ее с помощью "delete".