工作中优化一段代码,代码中有一大段分配堆内存的内容,我觉得这段代码太长了,更适合放在子函数里面。

我把指针作为参数,然后在子函数中malloc分配内存,结果出现了问题,函数结束后,以参数传进来的指针并没有指向分配的内存。

比如说:

int fun(unsigned char *p, unsigned char **p1) {
p = (unsigned char *)malloc(N * sizeof(unsigned char));
if (NULL == p)
return -;
// 给二维指针p1分配
p1 = fun_set_p1();
if (NULL == p1) {
free(p);
return -;
}
return ;
} 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 -;
// 给二维指针p1分配
*p1 = fun_set_p1();
if (NULL == *p1) {
free(*p);
return -;
}
return ;
} unsigned char* p;
unsigned char** p1;
fun(&p, &p1);

其实就是指向指针的指针。

函数内值传递,拷贝一份,其指向的内存的内容改变了,参数指向的内存的内容就跟着变了。

最新文章

  1. Mac下命令行中用sublime打开指定文件 设置方法
  2. 自定义Drawable
  3. Logstash+kibana+ ElasticSearch+redis
  4. cms中if标签的使用
  5. Treblecross 博弈SG值
  6. BZOJ_1100_[POI2007]对称轴osi_KMP+计算几何
  7. markdown 【demo】
  8. 1.继承(extends)、超类(superClass)、子类(subClass)
  9. 链表(list)使用注意
  10. 读取2007以上版本的excel(xslx格式)
  11. npm更新升级
  12. 强化学习论文(Scalable agent alignment via reward modeling: a research direction)
  13. Servlet开发
  14. BOS物流项目第十三天
  15. python递归和二分法
  16. Kafka设计解析(二十一)Kafka水位(high watermark)与leader epoch的讨论
  17. Oracle 数据库执行 操作系统的命令
  18. idea过期激活
  19. PHP正则表达式基本语法
  20. 【巷子】---vue项目打包---基本使用---【vue】

热门文章

  1. erlang数字转字符串
  2. WPF动画结束后的行为方式
  3. 【codeforces 768A】Oath of the Night's Watch
  4. 百度UEditor上传图片-再再总结一次
  5. Java:JSON解析工具-org.json
  6. ik_max_word ik_smart
  7. PAT 1001-1010 题解
  8. jieba(结巴)—— Python 中文分词
  9. Oracle 学习笔记 18 -- 存储函数和存储过程(PL/SQL子程序)
  10. Chrome浏览器离线安装 Postman 5.X 报错