什么时候应该在 C 中使用 free() ?

发布于 2024-12-04 01:39:04 字数 2444 浏览 9 评论 0原文

该代码按预期工作,但它从未释放 malloc() 分配的内存。

我尝试在任何可以的地方释放内存,但无论我在哪里这样做,它都会破坏程序。具体来说,我收到“双重释放或损坏错误”。这更多的是关于 free() 和 malloc() 实际做什么的问题?免费的所有问题主要在于:

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

printf("CSA WC version 1.0\n\n");

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

//printf("filename:%s\n",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: %i\n",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: %s\n",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:%s\n",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] != '\0'){

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

}

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

return dest;
}

The code works as it is supposed to, though it never frees the memory allocated by malloc().

I have tried to free memory in any place that I can, but no matter where I do it, it breaks the program. Specifically, I get a "double free or corruption error." This is more of a question as to what free() and malloc() actually do? All of the problems with free are in the main:

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

printf("CSA WC version 1.0\n\n");

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

//printf("filename:%s\n",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: %i\n",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: %s\n",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:%s\n",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] != '\0'){

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

}

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

return dest;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

往事风中埋 2024-12-11 01:39:04

一般来说,您只需释放动态为您保留的内存即可。这意味着如果您有这样的语句:

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

那么您需要释放由 malloc 分配(保留)的内存。
如果您不确定在哪里释放它,那么可以在程序结束时使用 free 来释放它;

free(my_int_pointer);

在您的文件中,每当您读取的文件中有新行(在 while(done==0) 循环中)时,似乎都会分配内存。因此,每次在 this 循环中的 if 之后,您都必须释放变量所使用的内存。

此外,您需要释放为 readline 变量分配的内存。但正如之前指出的那样,那里可能存在内存泄漏。

希望这有帮助。

编辑:好的 - 我已经想知道 csestrcpy 函数了。让我们看一下这个函数:

char* csestrcpy2(char* src){
    int i = 0;
    char *dest;
    char t;
    dest = (char*) malloc(MAX_LINE); /*<<- This allocates memory that has to be freed*/
    while( src[i] != '\0'){
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0';
    //printf("length:%i\n",i);
    free(dest);                  /* This frees the memory, but you return a pointer */
    return dest;                 /* to this memory. this is invalid.                */
}

但是您可以释放的是该函数中的 src 指针。但请记住:释放底层内存后,指针无法保存信息!它只是指向内存中不应再写入或读取的位置。

此外,只要不存在“\0”,该函数就会复制字符串。如果没有终结者会发生什么?该函数继续从一些不应该复制的内存地址进行复制!

你不应该使用该功能;)

In general you only have to free memory that has been reserved for you dynamically. That means if you have a statement like this:

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

than you need to free the memory that was allocated (reserved) by malloc.
if you are unsure where to free it than just free it at the end of the program, by using free;

free(my_int_pointer);

In your file it looks like there will be memory allocated whenever there is a new line in the file you read (in the while(done==0) loop). so everytime after the if in the this loop you have to free the memory that was used by the variable.

Furthermore you need to free the memory that was allocated by for the readline variable. But as it was pointed out before you may have a memory leak there.

Hope this helps.

edit: Okay - I was already wondering about the csestrcpy function. Lets have a look at this function:

char* csestrcpy2(char* src){
    int i = 0;
    char *dest;
    char t;
    dest = (char*) malloc(MAX_LINE); /*<<- This allocates memory that has to be freed*/
    while( src[i] != '\0'){
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0';
    //printf("length:%i\n",i);
    free(dest);                  /* This frees the memory, but you return a pointer */
    return dest;                 /* to this memory. this is invalid.                */
}

What you could however free is the src pointer in that function. but remember: the pointer cannot hold information after the underlying memory is freed! It just points to a place in memory where it should not write or read anymore.

Furthermore the function copys the string as long as there is no '\0'. What happens if there is no terminator? The function keeps on copying from some memory adresses where it should not!

you should not use that function ;)

躲猫猫 2024-12-11 01:39:04

每次成功调用 malloc() 都需要调用 free()

这并不一定意味着您的代码中需要有相同数量的 malloc()free() 调用;这意味着,对于程序运行时执行的每个 malloc() 调用,您都应该调用 free(),并将从 malloc() 获得的指针值传递给它。 )malloc() 分配内存; free() 告诉系统您已完成分配的内存。

(几乎可以肯定,当程序终止时,您可以不使用 free()ing 分配的内存,因为它将被操作系统回收,但作为风格和良好实践的问题,您仍然应该将 malloc()free() 匹配。)

我忽略了 calloc()realloc() 来电。

There needs to be a call to free() for each successful call to malloc().

That doesn't necessarily mean that you need to have equal numbers of malloc() and free() calls in your code; it means that for every malloc() call that's executed when your program runs, you should call free(), passing it the pointer value you got from malloc(). malloc() allocates memory; free() tells the system that you're done with the allocated memory.

(You can almost certainly get away with not free()ing allocated memory when your program terminates, since it will be reclaimed by the operating system, but just as a matter of style and good practice you should still match malloc()s with free()s.)

I'm ignoring calloc() and realloc() calls.

尴尬癌患者 2024-12-11 01:39:04

动态内存分配(malloc)分配请求大小的内存块,并返回指向该块开头的指针。由于我们已从内存中取出该块,因此最好在任务完成后将其返回到内存。

现在作为您问题的答案,为了始终安全起见,您可以在返回之前调用自由函数。

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

Dynamic memory allocation (malloc) allocates a memory block of requested size, and returns a pointer to the start of this block.Since we have taken this block from memory so its a good practice to return this back to memory after completion of task.

Now as answer of your question , To be always on safe side you can call free function before making return.

main{
    int *i;
    ..
    ..
    i=(int *)malloc(sizeof(int));
    ...//so something with i
    ..
    free(i);
    return 0;
}
冬天的雪花 2024-12-11 01:39:04

mallocfree 视为“开始”和“结束”。任何时候调用 malloc 时,都执行您需要的操作,完成后,始终调用 free。确保只释放一次,两次释放是运行时错误。

如果您以某种方式丢失了 malloc 返回的值(是的,这就是您的代码所发生的情况),那么您就会发生内存泄漏(地狱之门打开了,yada yada)。

重申一下:释放 malloc 返回的任何内容(null 除外)。

Think of malloc and free as "begin" and "end". ANY time you call malloc, do what you need to and once you're done, always call free. Make sure to only free it once, double-free is a runtime error.

If you somehow lose the value returned by malloc (yes, this is what's happening with your code), then you have a memory leak (and the gates of hell open up, yada yada).

To re-iterate: free whatever malloc returns (except null).

晚雾 2024-12-11 01:39:04

作为一般规则,对于每个 malloc 都应该有一个相应的 free。但是,您不能两次释放某物(正如您现在已经注意到的那样)。我在您的代码中没有看到任何对 free 的调用,因此无法说出您的问题所在,但我立即注意到您 malloc 一些内存并分配了它到循环内部的 readline ,但您没有在循环结束时对 readline 调用 free ,因此您在那里泄漏了内存。

As a general rule, for every malloc there should be a corresponding free. You cannot however free something twice (as you have noticed by now). I don't see any calls to free in your code, so it's impossible to say where your problem lies, but I noticed right away that you malloc some memory and assign it to readline inside of a loop, yet you don't call free on readline at the end of the loop, so you are leaking memory there.

很快妥协 2024-12-11 01:39:04

此行:

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

被它旁边的行覆盖,因此可以将其删除。

您还应该在最后一个循环中的 count++ 之后添加 free(readline) 以释放 malloc 创建的内存。

This line:

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

is being overriden by the line next to it, so it can be removed.

You should also add free(readline) after count++ in the last loop to free the memory created by malloc.

疯到世界奔溃 2024-12-11 01:39:04
        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”释放它。

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

This should work.

In general - any memory allocated dynamically - using calloc/malloc/realloc needs to be freed using free() before the pointer goes out of scope.

If you allocate memory using 'new' then you need to free it using 'delete'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文