如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示:

void Create(A** addr);

其中传递的参数是二级指针。为什么?

我们先看一下完整的动态内存分配函数的简单例子:

struct A {
int a = 0;
int b = 0;
int c[3];
}; void Create(A** addr) {
printf("a1: %p\n", addr);
*addr = new A();
printf("a2: %p\n", addr);
} int main() {
A *a;
printf("a0: %p\n", a);
Create(&a); // 传递二级指针值
printf("a4: %p\n", a);
return 0;
}

我们看下函数运行结果:

我们看到传进去的*a的值改变了,而且这个改变作用到了*a本身

在看下我们一般情况下想到的分配方式:

struct A {
int a = 0;
int b = 0;
int c[3];
}; void Create(A* addr) {
printf("a1: %p\n", addr);
addr = new A();
printf("a2: %p\n", addr);
} int main() {
A *a = nullptr;
printf("a0: %p\n", a);
Create(a); 传进去指针本身
printf("a4: %p\n", a);
return 0;
}

同时我们在看下结果:

我们看到对指针的操作,并没有作用到指针本身。这是因为哪怕我们传进去的是个指针,但是还是以值传递的方式传递指针的值。

具体的过程是,我们在*a传递到函数里面时,函数自身创建了一个中间变量,我们姑且称他为temp,这个temp的值为 a,我们后面进行new之后也只是简单的将

分配后的内存地址给了temp,所以才会出现上面结果。

但是对于二级指针而言,传进去的是指针的地址,对指针地址所指值进行操作,当然会改变指针本身的值。

其实该种方式也可以等价于:

struct A {
int a = 0;
int b = 0;
int c[3];
}; void Create(A* &addr) {
printf("a1: %p\n", addr);
addr = new A();
printf("a2: %p\n", addr);
} int main() {
A *a;
printf("a0: %p\n", a);
Create(a);
printf("a4: %p\n", a);
return 0;
}

结果如下所示:

我们传进去的是指针的引用,当然会作用到指针本身。

C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题的更多相关文章

  1. C标准库-数值字符串转换与内存分配函数

    原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...

  2. Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)

    Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc) 来源:http://blog.csdn.net/chunyexiyu/article/ ...

  3. C语言之内存分配函数

    #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { /********* ...

  4. 内存分配函数malloc、realloc、calloc、_alloca

    1.内存分配函数_alloca.malloc.realloc.calloc: _alloca 函数原型void * __cdecl _alloca(size_t); 头文件:malloc.h _all ...

  5. 【转】【C/C++】内存分配函数:malloc,calloc,realloc,_alloca

    转自:http://www.cnblogs.com/particle/archive/2012/09/01/2667034.html#commentform malloc: 原型:extern voi ...

  6. Linux内核中常见内存分配函数(二)

    常用内存分配函数 __get_free_pages unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) __get_f ...

  7. Linux内核中常见内存分配函数【转】

    转自:http://blog.csdn.net/wzhwho/article/details/4996510 1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页 ...

  8. Linux内核中常见内存分配函数

    1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...

  9. C语言内存分配函数malloc——————【Badboy】

    C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文 ...

随机推荐

  1. mysql 面试100 问(精华学习)。待开始理

    https://juejin.im/post/6850037271233331208 https://juejin.im/entry/6844903681091977229

  2. binary hacks读数笔记(objdump命令)

    一.首先看一下几个常用参数的基本含义: objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它还有其他作用,下面以ELF格式可执行文件test为例详细介绍: 1.objdump -f ...

  3. logback怎么写?分类输出日志到不同的文件

    此appender有顺序,最好不要乱调顺序,输出日志如下: drwxr-xr-x 2 root root 4096 Dec 3 00:00 2019-12-02drwxr-xr-x 2 root ro ...

  4. 支持jewel版本的calamari

    之前测试了下,发现calamari不支持jewel版本的,是因为接口了有了一些变化,在提出这个问题后,作者给出了回答,说肯定会支持的,并且做了一点小的改动,就可以支持了,这个作者merge了到了git ...

  5. 动态JavaWeb工程的架构问题

    B/S 网络应用的分层 前端(表示层) 后端( 业务逻辑层, 数据库访问层 ) 分层的目的->分模块->解耦 1,表示层---和用户直接交互 html,js,css, servlet 2, ...

  6. cookie和session的关系和区别

    1.为什么会用到cookie和session 由于http请求是一种无状态的请求,一旦数据交换完毕便会关闭请求,再次交换数据则要再次发起请求,所以服务端无法通过连接追踪会话,确定用户身份,而cooki ...

  7. 通过RayFire为图形添加二次破碎效果

    在完成3D建模之后,RayFire能帮助用户制作多种类型的破碎效果,如均匀碎片.放射状碎片.木碎等效果.另外,用户还可以利用RayFire的碎片选取功能,为图形进行二次破碎,以达到增加局部碎片的效果. ...

  8. 如何制作C语言基本数据类型的思维导图

    在使用C语言编写程序时,数据类型是一个非常重要的内容,任何一个不被重视的数据错误都会使编译器无法翻译,导致程序报错. 使用思维导图来梳理各个数据类型是一个很有效的记忆方法,接下来就为大家展示一下我用i ...

  9. 简单几步就能把素材变成大片?老司机推荐Vegas

    "素材编辑"一般分为两种,一种是对时间线素材长度和位置的编辑,另一种就是遮罩法操作. 第一种,裁剪素材(将素材在我们选定的位置一分为二),对时间线上的素材进行裁剪,有两种方法: 一 ...

  10. 用MindManager画思维导图的好处有哪些?

    大家都听说过思维导图吧?有没有将这样一种图形思维工具真正运用到我们的日常生活中去呢?是否真的知道思维导图怎么用呢?今天小编就来给大家讲一讲,思维导图怎么用. 老规矩,先给大家讲一讲小编用的软件跟系统, ...