简体   繁体   English

如何为局部变量释放动态分配的内存?

[英]how to free the dynamically allocated memory for a local variable?

Sample program: 示例程序:

#include <stdio.h>
#include <malloc.h>

void f(int n) {
     char *val = (char *) malloc(12*sizeof(char));
     val = "feels....";

     printf("%s", val);

 //  free val;     // if enable, compile time error: expected ';' before 'val'   free val;   
 }

 int main()
 {
      f(1);

      return 0;
 }

Is it required to free the memory which is dynamically allocated ? 是否需要释放动态分配的内存? if yes, how to. 如果是,如何。

Yes, you need to free the memory. 是的,您需要释放内存。 But when you allocate memory for a string, the way to populate the string is not to assign a string to it as that replaces the memory you've allocated. 但是,当您为字符串分配内存时,填充字符串的方法是不为其分配字符串,因为这会替换您已分配的内存。 Instead you're meant to use the function strcpy like this... 相反,您应该像这样使用功能strcpy ...

char *val = malloc(12*sizeof(char));
strcpy(val,"feels....");

printf("%s", val);
free(val);

Instead of this: 代替这个:

 char *val = (char *) malloc(12*sizeof(char));
 val = "feels....";  // val points now to the string literal ""feels...."
                     // discarding the value returned by malloc
 ...
 free(val);          // attempt to free the string literal which will
                     // result in undefined behaviour (most likely a crash)

you probably want this: 您可能想要这样:

 char *val = malloc(12*sizeof(char));  // in C you don't cast the return value of malloc
 strcpy(val, "feels....");  // the string "feels...." will be copied into
                            // the allocated buffer
 ...
 free(val);          // free memory returned previously by malloc

The compilation problem is because free is a function, you need to put its argument in parentheses. 编译问题是因为free是一个函数,您需要将其参数放在括号中。

free(val);

The other problem is a memory leak. 另一个问题是内存泄漏。

Strings in C are really just pointers to (hopefully) blocks of memory containing char data. C中的字符串实际上只是(希望)指向包含char数据的内存块的指针。 The end of the string is denoted by a char with value 0. The thing to remember is that your variable is simply a pointer like any other pointer. 字符串的结尾用值为0的char表示。要记住的是,变量就像其他任何指针一样,只是一个指针。 So... 所以...

 char *val = (char *) malloc(12*sizeof(char));

The above line dynamically allocates a block of memory and assigns a pointer to it to val . 上一行动态分配了一个内存块,并将指向它的指针分配给val

 val = "feels....";

The above line assigns a pointer to a string literal to val overwriting the previous pointer that was in val . 上述行分配一个指针指向一个字符串文字到val重写先前的指针,这是在val It has not touched, in any way, the block of memory that was malloc ed in the first line. 它没有以任何方式触及第一行中已malloc的内存块。 Furthermore, you have lost any reference you had to the malloc ed block so it has leaked. 此外,您丢失了对malloc ed块的任何引用,因此它泄漏了。 There's no way to free it. 无法free它。

String literals are usually created at compile time and the memory they occupy will be part of the program. 字符串文字通常在编译时创建,它们所占用的内存将成为程序的一部分。 This means they haven't come from the heap (where malloc gets its memory from. This means, in turn, when you try to free a string literal, bad things happen. On modern architectures, the program text is protected from writes at the OS level so trying to free part of it will almost certainly crash your program. 这意味着它们并非来自堆( malloc从那里获取内存。这又意味着,当您尝试free字符串文字时,会发生不好的事情。在现代体系结构上,程序文本受到保护,无法在操作系统级别,因此尝试free一部分几乎肯定会导致程序崩溃。

As long as you do not want to change the content of the string, you do not need to malloc space to it. 只要你不想改变字符串的内容,你不需要malloc空间给它。 You can omit the malloc line (and the corresponding free ) and your program will still work. 您可以省略malloc行(以及相应的free ),您的程序仍然可以运行。

f you do want to change the string, the easiest way to get a mutable copy of a string literal is to use strdup : 如果您确实想更改字符串,则获取字符串文字的可变副本的最简单方法是使用strdup

char *val = strdup("feels....");

// Do stuff with the string

free(val); // strdup strings need to be freed

strdup is a Posix function but not a C standard function so your platform might not have it. strdup是Posix函数,而不是C标准函数,因此您的平台可能没有它。 It's pretty simple to implement your own, though. 但是,实现自己的过程非常简单。

char* myStrDup(const char* thingToDup)
{
    char* ret = malloc(strlen(thingToDup) + 1); // strlen returns the length without the terminating nul. Hence add 1 to it to allocate
    strcpy(ret, thingToDup); // Copies the entire string including the terminating nul.
    return ret;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM