You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言字符串无需内存分配?mmc-utils中print_str实现疑问

解答:C语言字符串字面量的内存机制

我在处理mmc-utils的do_erase函数时看到如下代码:

int do_erase(int nargs, char **argv)
{
    int dev_fd, ret;
    char *print_str;
    __u8 ext_csd[512], checkup_mask = 0;
    __u32 arg, start, end;

    ...

    if (strcmp(argv[1], "legacy") == 0) {
        arg = 0x00000000;
        print_str = "Legacy Erase";
    } else if (strcmp(argv[1], "discard") == 0) {
        arg = 0x00000003;
        print_str = "Discard";
    } else if (strcmp(argv[1], "secure-erase") == 0) {
        print_str = "Secure Erase";
        checkup_mask = EXT_CSD_SEC_ER_EN;
    }

    ...

    if ((checkup_mask & ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) !=
                            checkup_mask) {
        fprintf(stderr, "%s is not supported in %s\n",
            print_str, argv[4]);
        ret = -ENOTSUP;
        goto out;
    }

out:
    printf(" %s %s!\n\n", print_str, ret ? "Failed" : "Succeed");
    close(dev_fd);
    return ret;
}

我无法理解该函数未对print_str进行栈或堆内存分配却能正常工作的原因。虽然栈上有字符串指针,但C语言在运行时不存在自动栈分配的“魔法”吧?该代码编译运行均无问题,想请教原理,同时确认:C语言中使用字符串是否真的无需内存分配?


核心原理:字符串字面量的存储机制

C语言中,像"Legacy Erase"、"Discard"这类用双引号包裹的字符串字面量,在编译阶段就会被编译器处理:

  • 它们会被存储到程序的**只读数据段(.rodata)**中,这个区域属于程序可执行文件的一部分,程序启动后会被加载到内存里,生命周期和整个程序一致。
  • 代码中print_str = "Legacy Erase";这行,并不是把字符串内容复制到栈或堆上,而是把只读数据段中该字符串的起始地址赋值给栈上的指针变量print_str。

关于内存分配的澄清

C语言中使用字符串并非都不需要内存分配,分两种情况:

  • 字符串字面量:如代码中的用法,编译时已分配在只读段,运行时只需用指针指向它即可,不需要手动调用malloc或在栈上开辟数组。
  • 动态生成/可变字符串:比如需要接收用户输入、拼接字符串、修改内容的场景,就必须手动分配内存——要么用栈上的字符数组(如char buf[256];),要么用malloc/calloc在堆上分配空间。

代码合法性说明

这段代码完全合法,因为print_str始终指向只读数据段中有效的字符串地址,这些字符串在程序运行期间一直存在,不会出现野指针或内存非法访问的问题。后续用printf、fprintf输出时,本质是通过指针访问只读段里的字符串内容,自然能正常工作。

内容的提问来源于stack exchange,提问作者led

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:40:31