使用二级指针传出参数

使用指针传出参数时,要注意指针所指向的内存是在函数内分配的还是在函数外分配的,以及是不是在堆上分配的。

定义一个指针,但是并没有分配指针指向对象所需的内存空间;当函数返回后,此函数栈中的内存会被释放掉,不要让指针指向此函数栈中的内存空间;

要指向堆上或此函数外的内存空间。


1. 参数传递的原则是:形参传给实参,不能反向传递;

2. 一级指针可以在函数内部修改实参指针指向的内容;

如: 

void f(char *p) 

{p[2] = a;
//由实参指向的函数外部的数组的内容就被改变了。……
}
如果我们想改变实参本身呢?也就是说,我们连指针值都要改变,如果使用:

void f(char *p) 
{	
    p = (char *)malloc(10 * sizeof(char))	
    //或C++中:p = new char[10];	
……}
就不行了,因为在函数内部不能通过改变形参的值来改变实参。

但是,可以通过二级指针来改变指针值。


void f(char **p)
{    
    *p = new char[10];
    *p[2] = a;
    delete char[];
……}


可以这样说,传入一个N级指针,就可以修改N-1级指针,原因还是C的参数传递是值传递的,直接修改形参根本改变不了实参,

但可以改变形参指针指向的内容,而N级指针指向的内容就是一个N-1级指针。



注意指针所指向的内存是在函数内分配的还是在函数外分配的,以及是不是在堆上分配的。

你定义了一个指针,但是并没有分配指针指向对象所需的内存空间;当函数返回后,此函数栈中的内存会被释放掉,

不要让指针指向此函数栈中的内存空间,要指向堆上或此函数外的内存空间。



代码范例:

#include <stdio.h>
#include <string.h>
char *f_void(void);
void f_2ptr(char **ret);
void f_1ptr(char *ret);
 
 
int main()
{
    char havec[] = "this is a b c d e f";
    char **ret; // Alloc memory for secondary pointer
    char *tmp;  // Alloc memory for first pointer
 
    ret = &tmp; // this is imporint, why?
    f_2ptr(ret);
    printf("%s\n",tmp); // Ok
    tmp = f_void();
    printf("%s\n",tmp); // Ok
 
    f_1ptr(havec);
    printf("havec = %s\n",havec);
 
    return 0;
}
 
void f_2ptr(char **ret) // output argument, memory is alloced in the function
{
    static char aa[] = "this is output argument";  // 该处的static指定数组aa[]指向全局变量所在空间
    *ret = aa;
}
 
void f_1ptr(char *ret) // memory is alloced outside the function
{
    char *tmp;
    if((tmp = index(ret,'c')) ==NULL) // this is just a example
        return ;
    *(tmp+4) = '\0';
}
 
 
char *f_void(void) // return a pointer, memory is alloced in global
{
    return "this is return value";
}




运行结果:

root@startech-945GCM-S2C:~/Cisco-MAPI-Test# ./ok
this is output argument
this is return value
havec = this is a b c d