使用字符串文字初始化时,我应该释放char*
个变量吗?对我来说,语法会让我假设它们只是堆栈分配,但这个例子告诉我,它们不是。
#include <stdlib.h>
#include <stdio.h>
static char* globalBuffer;
typedef struct Container {
char* buffer;
} Container;
Container* Container_new(char* buffer) {
Container* container = malloc(sizeof(Container));
container->buffer = buffer;
globalBuffer = buffer;
return container;
}
void Container_print(Container* container) {
if (container->buffer != NULL) {
printf("%s", container->buffer);
printf("\n");
}
else {
printf("Container contains a NULL-buffer.");
}
}
Container* stage() {
Container* container = Container_new("Test-string.");
Container_print(container);
return container;
}
int main() {
Container* container = stage();
Container_print(container);
free(container);
Container_print(container); // I know, this results in undefined behaviour
printf(globalBuffer);
printf("\n");
return 0;
}
我得到以下输出:
C:\Users\niklas\Desktop>gcc char_test.c
C:\Users\niklas\Desktop>a.exe
Test-string.
Test-string.
6>
Test-string.
C:\Users\niklas\Desktop>
因此,使用字符串文字初始化的char*
仍然存在,即使它超出了范围。
所以,我的问题,我应该释放这些char*
指针吗?这是正确的main()
吗?
int main() {
Container* container = stage();
Container_print(container);
free(container->buffer); // NEW
free(container);
Container_print(container);
printf(globalBuffer);
printf("\n");
return 0;
}
答案 0 :(得分:30)
你永远不会free()
记忆你没有malloc()
编辑。
编译器实现字符串文字的方式不是您的业务:它是一个实现细节。你可以free()
指向你使用malloc()
分配的内存的指针,只有那些,或者你冒着系统的生命危险。
理想情况下,malloc()
调用和free()
调用应出现在相同的“设计级别”(例如,在相同模块的同一实现文件中),并且它们应完全匹配:one {{每个free()
1}}。但这并不总是可行的。
(请注意,某些库会分配内存块,返回指向这些块的指针,并指示您释放它们。在这种情况下,您可以释放这些指针,但这是一个糟糕的设计实践,创建图书馆的人。)
答案 1 :(得分:30)
字符串文字的存储方式使它们在程序的生命周期内可用;如果你写
char *ptr = "This is a test";
所有写入ptr
的内容都是字符串文字"This is a test"
的地址。即使ptr
变量超出范围,字符串文字也会继续存在于其自己的内存部分中,而不是 malloc
使用的相同部分(至少,而不是在逻辑层面)。请注意,同一字符串文字的多个实例可以解析到同一位置; IOW,给出
char *p0 = "This is a test";
char *p1 = "This is a test";
p0
和p1
可能都包含相同的地址(由编译器决定是否多次出现字符串文字到同一位置)。
当您致电Container_new
时,您所做的只是将地址复制到container->buffer
和globalBuffer
;两者都指向独立于其中任何一个存在的同一事物。 free
- container
container->buffer
不会影响printf(globalBuffer);
指向的字符串文字,因此"Test-string."
仍会显示free(container->buffer);
。
总之,您应该不致电
malloc
此特定程序,因为您未将calloc
,realloc
或Container_new
调用的结果分配给它。
如果,OTOH,您已将Container* Container_new(char* buffer)
{
Container* container = malloc(sizeof(Container));
container->buffer = malloc(strlen(buffer) + 1); // Allocate memory to
if (container->buffer) // store a *new* instance
{ // of the input string.
strcpy(container->buffer, buffer); // This will need to be
} // freed before freeing
globalBuffer = buffer; // the container
return container;
}
写为
container->buffer
然后你 需要在释放container
之前释放{{1}}。