如何解引用C语言函数返回的指针?返回栈变量地址触发段错误如何解决
段错误含义、触发原因及修复方案
段错误的含义
段错误是程序访问了未被系统授权访问的内存地址时触发的运行时报错,触发场景通常包括访问已被释放的内存、空指针指向的内存、无读写权限的内存区域等。
本次报错的核心原因
- 你在
sum_returning_pointer函数内定义的局部变量z属于栈内存变量,栈内存变量的生命周期和所属函数完全绑定:函数执行结束返回后,对应的栈帧会被系统自动回收,z占用的内存会被标记为可复用,不再属于合法可访问的内存范围。 - 你返回了局部变量
z的地址&z,主函数后续对指针p解引用访问时,本质是访问已经被回收的非法内存,因此触发段错误。
另外你代码中void main(int *argc, char *argv[])是不规范的写法,C标准的main函数签名为int main(int argc, char *argv[]),虽然这不是本次报错的直接原因,但也建议修正。
正确的实现方案
方案1:在堆内存申请空间存储返回结果
使用malloc在堆上申请内存,堆内存的生命周期由开发者自主控制,不会随函数结束自动释放,使用完成后手动释放即可避免内存泄漏,是工业界最常用的实现方式:
#include <stdio.h> #include <stdlib.h> int *sum_returning_pointer(int *x, int *y) { int *z = (int *)malloc(sizeof(int)); // 增加空指针判断,避免内存申请失败导致的异常 if (z != NULL) { *z = (*x) + (*y); } return z; } int main(int argc, char *argv[]) { int a = 1, b = 2; int *p = sum_returning_pointer(&a, &b); if (p != NULL) { printf("Sum = %d\n", *p); // 使用完堆内存主动释放,避免内存泄漏 free(p); p = NULL; } return 0; }
方案2:主调函数提前分配结果内存,传入地址供被调函数写入
不需要动态申请内存,由上层调用者负责存储结果的内存空间,无内存泄漏风险,性能更优:
#include <stdio.h> // 第三个参数传入存储结果的内存地址 void sum(int *x, int *y, int *result) { *result = (*x) + (*y); } int main(int argc, char *argv[]) { int a = 1, b = 2; int result; sum(&a, &b, &result); printf("Sum = %d\n", result); return 0; }
方案3:static修饰局部变量(仅做原理了解,不推荐生产环境使用)
给局部变量加static修饰后,变量会存储在静态存储区,生命周期和整个程序运行周期一致,不会随函数结束释放,但该变量全局共享,多次调用或多线程场景下会出现值覆盖问题,存在线程安全隐患:
#include <stdio.h> int *sum_returning_pointer(int *x, int *y) { static int z; z = (*x) + (*y); return &z; } int main(int argc, char *argv[]) { int a = 1, b = 2; int *p = sum_returning_pointer(&a, &b); printf("Sum = %d\n", *p); return 0; }
内容的提问来源于stack exchange,提问作者Surya Bhusal
相关产品推荐
相关产品推荐

