子函数内malloc分配内存,论如何改变指针参数所指内存,二级指针、三级指针的应用
工作中优化一段代码,代码中有一大段分配堆内存的内容,我觉得这段代码太长了,更适合放在子函数里面。
我把指针作为参数,然后在子函数中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);
其实就是指向指针的指针。
函数内值传递,拷贝一份,其指向的内存的内容改变了,参数指向的内存的内容就跟着变了。
子函数内malloc分配内存,论如何改变指针参数所指内存,二级指针、三级指针的应用的更多相关文章
- C++ 数组长度 以及 数组名作为参数传递给函数 以及 为什么不在子函数中求数组长度
在看排序,首先是插入排序,思路理清后想用代码实现,然后问题来了: 如何求数组长度? 如果没记错,在Java中应该是有直接可用的方法的, Python中(序列)也有.len,在C/C++中,字符串倒是有 ...
- 【c++】指针参数是如何传递内存的
[c++]指针参数是如何传递内存的 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *) ...
- 【转】【c++】指针参数是如何传递内存的
参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...
- c++指针参数是如何传递内存的
参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...
- 【转】【C/C++】内存分配函数:malloc,calloc,realloc,_alloca
转自:http://www.cnblogs.com/particle/archive/2012/09/01/2667034.html#commentform malloc: 原型:extern voi ...
- c malloc分配内存
php中的内存分配有用类似emalloc这样的函数,emalloc实际上是C语言中的malloc的一层封装,php启动后,会向OS申请一块内存,可以理解为内存池,以后的php分配内存都是在这块内存池中 ...
- <转载>内存管理内幕-动态分配的选择、折衷和实现 对malloc内存分配有个简单的描述,对内存管理有个大致的说明
这篇文章看后感觉不错,和我在glibc下的hurdmalloc.c文件里关于malloc的实现基本意思相同,同时,这篇文章还介绍了一些内存管理方面的知识,值得推荐. 原文链接地址为:http://ww ...
- C++ 内存、new与malloc分配内存区别?
一关于内存 1.内存分配方式 内存分配方式有三种: (1)从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2)在栈上创建. ...
- 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型
小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...
随机推荐
- .netcore consul实现服务注册与发现-集群完整版
原文:.netcore consul实现服务注册与发现-集群完整版 一.Consul的集群介绍 Consul Agent有两种运行模式:Server和Client.这里的Server和Clien ...
- [Ramda] Change Object Properties with Ramda Lenses
In this lesson we'll learn the basics of using lenses in Ramda and see how they enable you to focus ...
- Oracle 11g对依赖的推断达到字段级
在Oracle 10g下,推断依赖性仅仅达到了对象级.也就是说存储过程訪问的对象一旦发生了变化.那么Oracle就会将存储过程置为INVALID状态.所以在为表做了DDL操作后.须要把存储过程又一次进 ...
- Linux修改windows中文本文件出现的^M
换行符的Linux与windows文本文件是不一致的,需要通过 :%s/^M$//g 其中^M的输入使用ctrl+v+m 可以删除^M
- Spring MVC的RequestContextHolder使用误区 good
JShop简介:jshop是一套使用Java语言开发的B2C网店系统,致力于为个人和中小企业提供免费.好用的网店系统. 项目主页:http://git.oschina.net/dinguangx/js ...
- 浏览器加载js文件顺序
在默认情况下,下载和执行js都会阻塞页面的渲染,当然现在浏览器支持并行下载,但仍然会阻塞图片等的下载和渲染,所以通常建议把js文件放body底.对于执行顺序,不管是外部js还是内部,只要 遇到< ...
- Function函数
一般大家都用这个写法来定义一个函数: function Name([parameters]){ functionBody }; //alert(typeof Name) // Function 当我们 ...
- Android GPS获取当前位置信息
package com.example.gpstest; import org.apache.http.util.LangUtils; import android.content.Context; ...
- Android设备与外接U盘实现数据读取操作
现在越来越多手机支持OTG功能,通过OTG可以实现与外接入的U盘等USB设备实现数据传输.关于OTG,可以参考: http://blog.csdn.net/srw11/article/details/ ...
- 《The Economist》的阅读
cover story(封面故事): Clean energy's dirty secret:清洁能源的肮脏幕后: 0. 词汇 respite:n. 缓解:暂缓:暂时的休息:缓期执行:也作及物动词(v ...