子函数内malloc分配内存,论如何改变指针参数所指内存,二级指针、三级指针的应用
工作中优化一段代码,代码中有一大段分配堆内存的内容,我觉得这段代码太长了,更适合放在子函数里面。
我把指针作为参数,然后在子函数中malloc分配内存,结果出现了问题,函数结束后,以参数传进来的指针并没有指向分配的内存。
比如说:
int fun(unsigned char *p, unsigned char **p1) { p = (unsigned char *)malloc(N * sizeof(unsigned char)); if (NULL == p) return -1; // 给二维指针p1分配 p1 = fun_set_p1(); if (NULL == p1) { free(p); return -1; } return 0; } unsigned char *p; unsigned char **p1 fun(p, p1);
运行完fun后,*p和**p1并没有发生变化。
指针作为参数不是传的是地址吗?怎么没变化呢?
其实这样想是一种误区,其实指针作为参数也是值传递,在函数中将参数复制一份而已。指向的是同一块内存地址。假设参数传的是int *p,函数内copy的j是int *p_1。在函数中操作*p_1,例如*p_1 = 1, 则p_1所指向的内容就变成了1.,由于他们是指向同一块地址,所以即使他们不是同一个指针*p所指向的内存也会被改变。
但如果让p_1指向其他的内存地址,则由于是值传递,p并不会因此而改变。
其实反汇编可以看出,参数的传递其实就是将变量放入新开辟的函数栈空间,也就是我说的“copy一份”,函数中再对栈空间里的内容操作,这就是值传递的本质。
所以这种情况该怎么办呢?
一种情况是函数 返回 指向新申请内存的指针
unsigned char* fun() { unsigned char* p = malloc(N * sizeof(unsigned char)); return p; }
但如果你需要设置多个指针就不合适了。
另一种办法就是使用二级指针、三级指针。
int fun(unsigned char **p, unsigned char ***p1) { *p = (unsigned char *)malloc(N * sizeof(unsigned char)); if (NULL == *p) return -1; // 给二维指针p1分配 *p1 = fun_set_p1(); if (NULL == *p1) { free(*p); return -1; } return 0; } unsigned char* p; unsigned char** p1; fun(&p, &p1);
其实就是指向指针的指针。
函数内值传递,拷贝一份,其指向的内存的内容改变了,参数指向的内存的内容就跟着变了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
· 用 C# 插值字符串处理器写一个 sscanf
2016-06-14 C struct结构体内存对齐问题