使用字符串文字初始化时,是否应该释放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;
}

最佳答案

字符串文字的存储方式在程序的整个生命周期内都可用。如果你写

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";
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->buffer,然后再释放container

关于c - 我应该释放使用字符串文字初始化的char *吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9504588/

10-11 19:44