zoukankan      html  css  js  c++  java
  • 子函数内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);

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

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

  • 相关阅读:
    二分查找
    bracketed-paste-magic:zle:41: not enough arguments for -U
    逗号表达式返回值
    requestAnimationFrame实现一帧的函数节流
    phaser常用API总结
    table表头固定问题
    接口防刷的方法
    雪碧图background-position的rem用法
    sphinx 增量索引与主索引使用测试
    msysgit ls 中文显示
  • 原文地址:https://www.cnblogs.com/rixiang/p/9183873.html
Copyright © 2011-2022 走看看