我应该释放使用字符串文字初始化的 char* 吗? [英] Should I free char* initialized using string-literals?

查看:32
本文介绍了我应该释放使用字符串文字初始化的 char* 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Should I free char* variables when they were initialized using string literals? To me, the syntax would lead me to the assumption that they are only stack-allocated, but this example showed me, they are not.

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

    return 0;
}

我得到以下输出:

C:Users
iklasDesktop>gcc char_test.c

C:Users
iklasDesktop>a.exe
Test-string.
Test-string.
­6>
Test-string.

C:Users
iklasDesktop>

所以,用字符串文字初始化的 char* 仍然存在,即使它超出了范围.

So, the char* initialized with string-literals does still exist, even it got out of scope.

那么,我的问题是,我应该释放这样的 char* 指针吗?这会是正确的 main() 吗?

So, my question, should I free such char* pointers? Would this be the correct main()?

int main() {
    Container* container = stage();
    Container_print(container);

    free(container->buffer);    // NEW
    free(container);
    Container_print(container);

    printf(globalBuffer);
    printf("
");

    return 0;
}

推荐答案

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

String literals are stored in such a way that they're available for the lifetime of the program; if you write

char *ptr = "This is a test";

所有写入ptr 的是字符串文字"This is a test"地址.即使 ptr 变量超出范围,字符串文字仍继续存在于它自己的内存部分中,这与 malloc<使用的部分不同/code> (至少,不是在逻辑级别).请注意,同一字符串文字的多个实例可能解析到相同的位置;IOW,给定

all that's written to ptr is the address of the string literal "This is a test". Even if the ptr variable goes out of scope, the string literal continues to exist in its own section of memory, which is not the same section used by malloc (at least, not at a logical level). Note that multiple instances of the same string literal may resolve to the same location; IOW, given

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

p0p1 可能都包含相同的地址(是否将多次出现的字符串文字映射到同一位置取决于编译器).

p0 and p1 may both contain the same address (it's up to the compiler whether multiple occurrences of string literals are mapped to the same location or not).

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

When you call Container_new, all you're doing is copying an address to container->buffer and globalBuffer; both wind up pointing to the same thing that exists independently of either of them. free-ing container doesn't affect the string literal that container->buffer points to, so printf(globalBuffer); still displays "Test-string.".

总而言之,你不应该调用

In summary, you should not call

free(container->buffer);

对于这个特定程序,因为您没有将 malloccallocrealloc 调用的结果分配给它.

for this particular program, since you didn't assign the result of a malloc, calloc, or realloc call to it.

如果 OTOH,你已经将 Container_new 写成

If, OTOH, you had written Container_new as

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.

then you would need to free container->buffer before freeing container.

这篇关于我应该释放使用字符串文字初始化的 char* 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆