会,而且是典型的未定义行为。函数栈帧退出后,局部变量所占内存立即失效,返回其地址会导致悬空指针,后续解引用可能读垃圾值、触发段错误或偶发崩溃。

返回局部变量的指针会崩溃吗
会,而且是典型的未定义行为。函数栈帧退出后,局部变量(包括数组、对象、基本类型)所占内存立即失效,此时返回其地址,后续解引用 ptr 可能读到垃圾值、触发段错误,或看似正常但偶发崩溃。
常见错误写法:
int* bad_func() {
int x = 42;
return &x; // ❌ 危险:x 是栈上局部变量
}- 即使加
static修饰,也要注意线程不安全和重入问题 - 用
std::vector或std::string替代裸数组时,别返回&vec[0]—— 容器重分配后指针失效 - 调试时开启 AddressSanitizer(
-fsanitize=address)能快速捕获这类错误
用 new 分配的指针谁来 delete
返回 new 出来的指针意味着调用方必须负责释放,否则必然内存泄漏。这不是风格问题,而是资源契约——C++ 没有自动内存回收机制。
示例:
立即学习“C++免费学习笔记(深入)”;
int* create_int() {
return new int(123); // ✅ 合法,但 caller 必须 delete
}
// 调用方:
int* p = create_int();
// ... 使用 p ...
delete p; // ❌ 忘记这行就泄漏- 现代 C++ 更推荐返回
std::unique_ptr<int>,所有权明确且自动析构 - 若需共享所有权,用
std::shared_ptr<int>,但注意循环引用风险 - 绝对避免混合使用
new和free(),或malloc和delete
返回字符串字面量指针安全吗
安全。字符串字面量存储在只读数据段(.rodata),生命周期贯穿整个程序运行期,返回其地址不会出问题。
例如:
const char* get_msg() {
return "Hello, world!"; // ✅ 安全:字面量常量区地址
}- 必须声明为
const char*,不能去掉const—— 修改字面量是未定义行为 - 不要试图对返回值做
delete[]或free(),它不是堆分配的 - 若需修改内容,应复制到堆或栈缓冲区再操作
返回类成员指针要注意什么
返回成员指针本身(如 int MyClass::*)极少用;更常见的是返回指向成员的普通指针(如 &obj.member)。关键点在于对象生命周期必须长于指针使用期。
典型陷阱:
struct Data { int x = 100; };
Data* get_data_ptr() {
Data d;
return &d; // ❌ 错误:返回局部对象地址
}- 若对象由调用方传入(如参数为
Data& obj),返回&obj.x是安全的 - 若对象是类的私有成员,且函数是公有方法,返回
&this->member也合法,但需确保 this 所指对象未销毁 - 返回
this指针本身要格外小心:链式调用中若对象是临时量,obj.func().other()可能导致悬垂
返回指针最易被忽略的复杂点:生命周期管理责任是否清晰传递给了调用方。裸指针不携带所有权语义,int* 看不出该不该 delete、能不能缓存、是否线程安全——这些都得靠命名、文档、约定甚至代码审查来补足。


















