我应该使用字符串文字来释放char *吗?

我应该在使用字符串文字初始化时释放char*变量吗? 对我来说,语法会让我假设它们只是堆栈分配,但这个例子告诉我,它们不是。

 #include  #include  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(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; } 

字符串文字的存储方式使它们在程序的生命周期内可用; 如果你写

 char *ptr = "This is a test"; 

所有写入ptr都是字符串文字"This is a test" 。 即使ptr变量超出范围,字符串文字也会继续存在于其自己的内存部分中,这与malloc使用的部分不同(至少在逻辑级别不是这样)。 请注意,同一字符串文字的多个实例可能会解析到同一位置; 我,给定

 char *p0 = "This is a test"; char *p1 = "This is a test"; 

p0p1可以包含相同的地址(由编译器决定是否多次出现字符串文字到同一位置)。

当你调用Container_new ,你所做的只是将地址复制到container->bufferglobalBuffer ; 两者都指向独立于其中任何一个存在的同一事物。 free -ing container不会影响container->buffer指向的字符串文字,所以printf(globalBuffer); 仍显示"Test-string."

总之,你不应该打电话

 free(container->buffer); 

对于此特定程序,因为您没有为其分配malloccallocrealloc调用的结果。

如果,OTOH,你已经写了Container_new

 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之前你需要释放container->buffer

你永远不会free()你没有malloc() ed的malloc()

编译器实现字符串文字的方式不是您的业务:它是一个实现细节。 你可以free()指向你使用malloc()分配的内存的指针,只有那些,或者你冒着系统的生命危险。

理想情况下, malloc()调用和free()调用应出现在相同的“设计级别”(例如,在相同模块的相同实现文件中),并且它们应完全匹配:每个malloc()一个free() malloc() 。 但这并不总是可行的。

(请注意,某些库会分配内存块,返回指向这些块的指针,并指示您释放它们。在这种情况下,您可以释放这些指针,但这对创建库的人来说是一个糟糕的设计实践。 )