1

我很难理解何时以及何时不分配 char 数组堆/堆栈,具体取决于它们的声明方式。例如:

void test()
{
   char *str1 = "MyString1";  // do i need to free this ??
   char str2[] = "MyString2"; //this is clearly on the stack

}

我应该在退出 test() 之前调用 free(str1) 吗?

4

4 回答 4

3

你只需要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);
于 2021-02-17T09:48:20.647 回答
2

不,您不必同时释放:free()当您使用动态维度时总是使用malloc():您提供的两个声明之间的区别,除了一个是指针,另一个是数组之外,只是一个问题可编辑性:第一个是不可编辑的文字字符串,第二个是可编辑的,但它们都分配在堆栈上。

于 2021-02-17T09:48:15.383 回答
1

在这两个声明中

char *str1 = "MyString1";
char str2[] = "MyString2";

您只明确声明了一个字符数组str2。该数组具有自动存储持续时间,它所占用的内存将在退出声明它的函数后被释放。也就是说,在退出函数后,数组将不再活跃,它所占用的内存可以被其他对象重用。

malloc当使用内存分配函数作为或分配数组时,您必须调用该函数calloc

在第一个声明中,您声明了一个指向字符串字面量第一个字符的指针"MyString1"。字符串文字在内部存储为一个字符数组,定义如下

char unnamed_string_literal[] = { 'M', 'y', 'S', 't', 'r', 'i', 'n', 'g', '1', '\0' };

它具有静态存储持续时间,并且在退出该功能后将处于活动状态。

另一方面,指针本身具有自动存储持续时间,退出函数后,它所占用的内存可以重新使用。

于 2021-02-17T09:59:15.267 回答
1

字符串文字"MyString1""MyString2"存储在不同的数据段中(其他来自堆栈或堆)。

在第一种情况下,您正在创建一个auto类型为“pointer to char”的新变量(“str1”),并将字符串文字“MyString1”的地址复制到它。

第二种情况下,您正在创建一个auto类型为“char 的 9 元素数组”的新变量(“str2”)(大小取自字符串文字的长度),字符串文字“MyString2”的内容是复制到它。

auto变量始终是本地的并存储在堆栈中。

这两个变量都存储在系统堆栈中,并且没有分配任何内容。因此,打电话free()是没有意义的。

PS:在程序结束时调用free()也没有意义,因为操作系统会处理它。

于 2021-02-17T10:00:32.167 回答