未调用Malloc的C字符指针为何可分配新内存?代码疑问解析
关于字符串指针与内存分配的疑问解答
首先看你给出的这段能正常运行的代码:
#include <stdio.h> int main () { char *a = "Hello"; a = "Hello_World"; printf ("%s", a); return 0; }
咱们一步步拆解你的三个问题:
1. 为什么修改已初始化的字符串指针有时候需要用malloc?
你记的没错,但场景不一样!得区分两种核心操作:
- 修改指针的指向:就像你代码里做的,
a本来存着"Hello"的地址,后来直接让它存"Hello_World"的地址——这只是改变指针变量a自身的值,完全不需要malloc,因为你根本没碰字符串本身的内容。 - 修改字符串的内容:如果你想把原来的
"Hello"改成"Hello_World"(在原有内存空间里修改字符),这时候就不行了!因为"Hello"是字符串字面量,它存在程序的只读数据段(常量区),这块内存是不允许写入修改的。这时候才需要用malloc在堆上分配一块可写的内存,把"Hello"复制过去,再在这块可写内存里修改内容,比如:#include <stdio.h> #include <stdlib.h> #include <string.h> int main () { char *a = malloc(12); // 分配足够存"Hello_World"的空间 strcpy(a, "Hello"); strcpy(a, "Hello_World"); // 现在可以修改内容了 printf("%s", a); free(a); // 堆内存要手动释放 return 0; }
2. 新字符串"Hello_World"的内存分配在哪里?
"Hello"和"Hello_World"都是字符串字面量,它们在程序编译阶段就被放到了只读数据段(也叫常量存储区)。程序启动时,这块内存会被加载到内存中,属于程序的静态内存部分,不是运行时动态分配的。你的指针a只是指向了这块内存的起始地址而已。
3. 原字符串"Hello"的内存如何处理?
原字符串"Hello"依然躺在只读数据段里,只要程序没退出,它就一直占着内存。但你的指针a已经不再指向它了,它变成了一块“无人认领”的常量内存——不过完全不用操心,因为常量区的内存是由操作系统在程序结束后统一回收的,不需要你手动释放(也没法手动释放,free只能用于堆上分配的内存)。
内容的提问来源于stack exchange,提问作者Vinay Varahabhotla
相关产品推荐
相关产品推荐

