我很难理解何时以及何时不分配 char 数组堆/堆栈,具体取决于它们的声明方式。例如:
void test()
{
char *str1 = "MyString1"; // do i need to free this ??
char str2[] = "MyString2"; //this is clearly on the stack
}
我应该在退出 test() 之前调用 free(str1) 吗?
我很难理解何时以及何时不分配 char 数组堆/堆栈,具体取决于它们的声明方式。例如:
void test()
{
char *str1 = "MyString1"; // do i need to free this ??
char str2[] = "MyString2"; //this is clearly on the stack
}
我应该在退出 test() 之前调用 free(str1) 吗?
你只需要free
你分配的东西。在您的示例中,没有什么要释放的,因为编译器为它创建了一个静态存储,它不能也不能被释放。
您是否必须释放某些东西也取决于您调用的函数。例如,如果您调用,strdup()
则需要释放返回的指针:
char *p = strdup("MyString");
free(p);
但是,例如,如果您打电话,strcpy()
那么您就不会免费打电话。
char buffer[100];
strcpy(buffer, "MyString");
// Don't free, as you created a local buffer on the stack and strcpy() doesn't allocate anything.
在这里你必须释放,因为你分配了它:
char *p = malloc(100);
strcpy(p, "MyString");
free(p);
不,您不必同时释放:free()
当您使用动态维度时总是使用malloc()
:您提供的两个声明之间的区别,除了一个是指针,另一个是数组之外,只是一个问题可编辑性:第一个是不可编辑的文字字符串,第二个是可编辑的,但它们都分配在堆栈上。
在这两个声明中
char *str1 = "MyString1";
char str2[] = "MyString2";
您只明确声明了一个字符数组str2
。该数组具有自动存储持续时间,它所占用的内存将在退出声明它的函数后被释放。也就是说,在退出函数后,数组将不再活跃,它所占用的内存可以被其他对象重用。
malloc
当使用内存分配函数作为或分配数组时,您必须调用该函数calloc
。
在第一个声明中,您声明了一个指向字符串字面量第一个字符的指针"MyString1"
。字符串文字在内部存储为一个字符数组,定义如下
char unnamed_string_literal[] = { 'M', 'y', 'S', 't', 'r', 'i', 'n', 'g', '1', '\0' };
它具有静态存储持续时间,并且在退出该功能后将处于活动状态。
另一方面,指针本身具有自动存储持续时间,退出函数后,它所占用的内存可以重新使用。
字符串文字"MyString1"
和"MyString2"
存储在不同的数据段中(其他来自堆栈或堆)。
在第一种情况下,您正在创建一个auto
类型为“pointer to char”的新变量(“str1”),并将字符串文字“MyString1”的地址复制到它。
在第二种情况下,您正在创建一个auto
类型为“char 的 9 元素数组”的新变量(“str2”)(大小取自字符串文字的长度),字符串文字“MyString2”的内容是复制到它。
这两个变量都存储在系统堆栈中,并且没有分配任何内容。因此,打电话free()
是没有意义的。
PS:在程序结束时调用free()
也没有意义,因为操作系统会处理它。