调用malloc的C程序触发bus error?Mac M2环境下问题排查求助
总线错误成因分析及代码修复
问题核心原因
你的代码触发zsh: bus error的根本原因是C语言的函数参数值传递特性,导致动态分配的内存地址没有传递回main函数的指针p:
- 调用
foo(p)时,foo的参数a是main中p的副本,二者是完全独立的变量。 foo里执行a = (int*)malloc(sizeof(int)),只是给副本a分配了内存地址,main里的原始指针p依然是未初始化的野指针(指向随机的非法内存地址)。- 后续执行
*p = 6时,你在尝试往一个不属于当前进程的非法地址写入数据,直接触发总线错误;free(p)也会因为p不是有效的堆内存地址而引发错误。
至于同行运行代码正常,这是未定义行为的随机性——野指针刚好指向了一块当前进程可读写的内存区域,但这种情况完全不可靠,属于错误代码的侥幸运行。
修复方案
有两种常见的修复方式,核心都是让动态分配的内存地址能被main的p获取到:
方式1:使用指针的指针(二级指针)作为函数参数
通过传递指针的地址,让foo可以直接修改main里的指针变量:
#include <stdio.h> #include <stdlib.h> void foo(int **a){ *a = (int*)malloc(sizeof(int)); } int main(){ int *p; foo(&p); // 传递p的地址 *p = 6; printf("%d",*p); free(p); return 0; }
方式2:让函数返回动态分配的内存地址
直接让foo返回malloc的结果,main里接收该地址:
#include <stdio.h> #include <stdlib.h> int* foo(){ return (int*)malloc(sizeof(int)); } int main(){ int *p = foo(); // 直接接收返回的内存地址 *p = 6; printf("%d",*p); free(p); return 0; }
内容的提问来源于stack exchange,提问作者tekkyprograms
相关产品推荐
相关产品推荐

