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

为何构造函数中为指针赋值字符串安全?局部数组指针却有风险?

C++字符串字面量与局部数组的内存区别解答

先看你给出的代码:

.h 文件

class test {
public:
    int Length;
    char* Name;
    int* ARR;
    test(int l, char* n, int* a);
    test();
};

.cpp 文件

test::test(int l, char* n, int* a){
    Length=l;
    Name=n;
    ARR=a;
}

main.cpp 文件

#include<iostream>
void InAFunc(test *kio) {
    int foo[3] = { 1,2,3 };
    *kio = test(7, "Hello!", foo);
}
int main() {
    test mmk;
    InAFunc(&mmk);
    std::cout << mmk.Name << mmk.ARR[1];
}

你的疑问是:明明访问mmk.ARR会因为局部变量foo被释放出问题,为什么给Name赋值字符串字面量却是安全的?

这得从C++里不同内存区域的特性说起:

  • 字符串字面量的内存归宿
    像"Hello!"这种字符串字面量,它并不是存放在函数的栈帧里,而是被编译器放在只读数据段(常量区)。这个区域的内存是在程序启动时就分配好的,并且会一直存在到整个程序运行结束才会被回收。所以当你把这个字符串的地址赋值给Name指针时,这个指针指向的是全局生命周期的内存,哪怕InAFunc函数执行完销毁了自己的栈帧,Name指向的字符串依然好好待在内存里,自然可以安全访问。

  • 局部数组foo的内存归宿
    而int foo[3]是函数InAFunc里的局部变量,它存放在栈内存中。栈内存的管理是跟着函数调用走的:函数执行时,栈帧被创建,局部变量在栈上分配空间;函数执行完毕,栈帧被销毁,栈上的局部变量内存会被标记为可复用(相当于被释放)。这时候mmk.ARR指向的就是已经被回收的栈内存,后续访问这个指针就属于“访问悬空指针”,会触发未定义行为(可能崩溃,也可能出现奇怪的结果)。

最后提个小建议:字符串字面量本质是const char[],虽然C++允许把它赋值给char*(兼容C的旧代码),但最好把test类里的Name声明为const char*,这样能避免不小心修改字符串字面量的风险(修改字符串字面量本身也是未定义行为)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:03:26