为何未分配内存却能初始化char指针?实例解析
我看到一段C++代码,用强制转换为char*的字符串字面量初始化结构体中的char指针,没有手动分配内存却能正常运行,还能输出完整字符串与数字。按我的认知这不应可行,想了解原因:
typedef struct{ char* c; int b; }st; #include <iostream> int main() { st a={ (char*)"qwertyuioplkjhgfdsazxccvbm", 3 }; std::cout<<a.c<<a.b<<std::endl; }
核心原因拆解:
字符串字面量本身就占用内存
字符串字面量(比如代码里的"qwertyuioplkjhgfdsazxccvbm")在程序编译阶段,会被编译器存储到程序的只读数据段(通常是.rodata段)里,这块内存是程序启动时就被加载到内存中的,不需要手动调用malloc或new去分配。char*只是一个指针,不是存储数据的容器
结构体里的char* c是一个指针变量,它的作用只是保存一块内存的地址,而不是自己存储字符串内容。这里它指向的就是只读数据段中字符串字面量的起始地址,所以不需要额外分配内存。强制转换的作用(但有风险)
C++标准中,字符串字面量的类型是const char[],直接赋值给char*是不允许的(会触发编译警告),所以代码里用(char*)做了强制类型转换,绕过了类型检查。但这种做法不安全:因为字符串字面量是只读的,如果后续尝试通过这个char*去修改字符串内容,会触发未定义行为(比如程序崩溃)。为什么能正常输出
std::cout输出char*类型时,会从指针指向的地址开始,一直读取到'\0'字符(编译器会自动给字符串字面量末尾加上这个结束标志),所以能完整输出整个字符串;而a.b是int类型,cout会直接输出它的数值,最终就会看到字符串和数字连在一起的输出结果。
规范写法建议
为了避免风险,应该把结构体中的char* c改为const char* c,这样就不需要强制转换,同时也能通过编译器检查防止误修改只读内存:
typedef struct{ const char* c; int b; }st; #include <iostream> int main() { st a={ "qwertyuioplkjhgfdsazxccvbm", 3 }; std::cout<<a.c<<a.b<<std::endl; }
内容的提问来源于stack exchange,提问作者בנצי G

