【发布时间】:2012-03-19 06:16:47
【问题描述】:
当使用字符串文字初始化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;
}
【问题讨论】:
-
顺便说一句 - 如果您的
printf(globalBuffer)和printf(container->buffer);包含 % 字符,它们会给您 jip。 -
有时一些元推理会有所帮助:你真的相信像字符串文字这样的基本概念只有在伴随着清理代码的情况下才能正确使用?肯定不是。
-
不,你不能那样做。您只能将 free() 用于使用 malloc()、calloc() 或 realloc() 动态分配的内存。
-
为了澄清,字符串文字也没有分配在堆栈上。它们是静态分配的,这意味着它们被烘焙到程序数据中并在程序加载时加载到内存中。所有指向字符串的指针都是指向程序数据中该位置的指针。它们既不是堆栈也不是堆。如果它们是在堆栈上分配的,那么您将无法安全地从函数中返回它们。
标签: c memory memory-management