示例程序:
#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;
}
是否需要释放动态分配的内存?如果是,如何释放。
是的,您需要释放内存。但是,当您为字符串分配内存时,填充字符串的方法不是为其分配字符串,因为这会替换您分配的内存。相反,你打算像这样使用函数strcpy
......
char *val = malloc(12*sizeof(char));
strcpy(val,"feels....");
printf("%s", val);
free(val);
取而代之的是:
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)
你可能想要这个:
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
编译问题是因为free
是一个函数,你需要把它的参数放在括号里。
free(val);
另一个问题是内存泄漏。
C 中的字符串实际上只是指向(希望(包含char
数据的内存块的指针。字符串的末尾由值为 0 的char
表示。要记住的是,您的变量只是像任何其他指针一样的指针。所以。。。
char *val = (char *) malloc(12*sizeof(char));
上行动态分配内存块,并将指向该内存块的指针分配给val
。
val = "feels....";
上面的行分配了一个指向字符串文本的指针,以val
覆盖val
中的上一个指针。它没有以任何方式触及在第一行中malloc
的内存块。此外,您已经丢失了对malloc
ed块的任何引用,因此它已泄漏。没有办法free
它。
字符串文字通常在编译时创建,它们占用的内存将成为程序的一部分。这意味着它们不是来自堆(malloc
从那里获取内存。这意味着,反过来,当您尝试free
字符串文字时,会发生不好的事情。在现代体系结构上,程序文本受到操作系统级别的写入保护,因此尝试free
其中的一部分几乎肯定会使程序崩溃。
只要您不想更改字符串的内容,就不需要为其malloc
空间。您可以省略malloc
行(以及相应的free
(,您的程序仍然可以工作。
如果您确实想更改字符串,获取字符串文本的可变副本的最简单方法是使用strdup
:
char *val = strdup("feels....");
// Do stuff with the string
free(val); // strdup strings need to be freed
strdup
是一个 Posix 函数,但不是 C 标准函数,因此您的平台可能没有它。不过,实现自己的非常简单。
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;
}