何时分配 char 数组堆与堆栈?
When is a char array heap vs stack allocated?
我很难理解何时以及何时不分配 heap/stack 字符数组,这取决于它们的声明方式。例如:
void test()
{
char *str1 = "MyString1"; // do i need to free this ??
char str2[] = "MyString2"; //this is clearly on the stack
}
我应该在退出 test() 之前调用 free(str1) 吗??
不,你不必释放两者:free()
总是在你 malloc()
某些东西到动态维度时使用:你提供的两个声明之间的区别,除了一个是一个指针,另一个是数组,只是可编辑性的问题:第一个是不可编辑的文字字符串,第二个是可编辑的,但它们都分配在堆栈上。
您只需 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);
在这两个声明中
char *str1 = "MyString1";
char str2[] = "MyString2";
您只显式声明了一个字符数组str2
。这个数组有自动存储期限,它占用的内存在退出声明它的函数后会被释放。即退出函数后数组将不存活,其占用的内存可以被其他对象重用。
当使用 malloc
或 calloc
等内存分配函数分配数组时,您必须调用 free 函数。
在第一个声明中,您声明了一个指向字符串文字 "MyString1"
的第一个字符的指针。字符串文字在内部存储为定义为
的字符数组
char unnamed_string_literal[] = { 'M', 'y', 'S', 't', 'r', 'i', 'n', 'g', '1', '[=11=]' };
具有静态存储时长,退出函数后会存活
另一方面,指针本身具有自动存储期限,退出函数后其占用的内存可以重复使用。
字符串文字 "MyString1"
和 "MyString2"
存储在不同的数据段中(其他来自堆栈或堆)。
在 first 的情况下,您正在创建一个新的 auto
类型为“指向 char 的指针”的变量(“str1”)和字符串的地址文字“MyString1”被复制到它。
在 second 情况下,您正在创建一个新的 auto
变量(“str2”),其类型为“9 元字符数组”(大小为从字符串文字的长度),并将字符串文字“MyString2”的内容复制到它。
The auto
variables are always local and are stored on the stack.
两个变量都存储在系统堆栈中,没有分配任何内容。因此,调用 free()
没有任何意义。
PS: 在程序结束时调用 free()
也没有意义,因为 操作系统 处理它。
我很难理解何时以及何时不分配 heap/stack 字符数组,这取决于它们的声明方式。例如:
void test()
{
char *str1 = "MyString1"; // do i need to free this ??
char str2[] = "MyString2"; //this is clearly on the stack
}
我应该在退出 test() 之前调用 free(str1) 吗??
不,你不必释放两者:free()
总是在你 malloc()
某些东西到动态维度时使用:你提供的两个声明之间的区别,除了一个是一个指针,另一个是数组,只是可编辑性的问题:第一个是不可编辑的文字字符串,第二个是可编辑的,但它们都分配在堆栈上。
您只需 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);
在这两个声明中
char *str1 = "MyString1";
char str2[] = "MyString2";
您只显式声明了一个字符数组str2
。这个数组有自动存储期限,它占用的内存在退出声明它的函数后会被释放。即退出函数后数组将不存活,其占用的内存可以被其他对象重用。
当使用 malloc
或 calloc
等内存分配函数分配数组时,您必须调用 free 函数。
在第一个声明中,您声明了一个指向字符串文字 "MyString1"
的第一个字符的指针。字符串文字在内部存储为定义为
char unnamed_string_literal[] = { 'M', 'y', 'S', 't', 'r', 'i', 'n', 'g', '1', '[=11=]' };
具有静态存储时长,退出函数后会存活
另一方面,指针本身具有自动存储期限,退出函数后其占用的内存可以重复使用。
字符串文字 "MyString1"
和 "MyString2"
存储在不同的数据段中(其他来自堆栈或堆)。
在 first 的情况下,您正在创建一个新的 auto
类型为“指向 char 的指针”的变量(“str1”)和字符串的地址文字“MyString1”被复制到它。
在 second 情况下,您正在创建一个新的 auto
变量(“str2”),其类型为“9 元字符数组”(大小为从字符串文字的长度),并将字符串文字“MyString2”的内容复制到它。
The auto
variables are always local and are stored on the stack.
两个变量都存储在系统堆栈中,没有分配任何内容。因此,调用 free()
没有任何意义。
PS: 在程序结束时调用 free()
也没有意义,因为 操作系统 处理它。