返回指针的函数及动态申请内存

首先,常量和全局变量以及静态变量都存储于静态存储区,而局部变量在栈区;
其次,内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)   从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。


一,

char   *GetMemory()
{
      char   *p= "hello";
      return   p;
}
int   main()
{
    char   *str=NULL;
    str=GetMemory();
    printf("%s",str);
    return   0;
}
=>上述结果可输出hello,因为p指针指向的“hello”是字符串常量,生存期为整个程序运行阶段。返回指针p给指针str等于将str指向“hello”的首地址,虽然GetMemory返回时指针p被释放,但处于静态存储区的字符串常量没有变化,因此可输出hello。


二,

char *GetMemory()

{
  char   *p;
  char  a[]="hello";
  p = a;
  return   p;
}
int   main()
{
    char   *str=NULL;
    str=GetMemory();
    printf("%s",str);
    return   0;
}
=>上述结果输出乱码,原因是指针p指向的地址为局部数组a的首地址,返回指针p给指针str等于将str指向a的首地址,当GetMemory返回时指针p和数组a都被释放,因此输出为乱码。


三,
char   *GetMemory()
{
  char   *p;
 char a[10] = "hello";
 p = malloc(10);
 memcpy(p,a,sizeof(a));
 return   p;
}
int   main()
{
    char   *str=NULL;
    str=GetMemory(   );
    printf("%s",str);
    return   0;
}

=>上述结果输出hello,因为GetMemory中用到动态申请内存,由malloc申请的内存属于从堆上分配,其生存期由我们决定,且让指针p指向动态申请的这块内存首地址。当GetMemory返回时指针p和数组a都被释放,但在堆上的这块内存没变化(存储着hello这个字符串),因此可输出hello。


四,

关于指针的传递上述两个函数中,GetMemory返回指针p给str,意思是让str指向指针p所指向的地址空间。又如

void GetMemory(char *p, int num)

{

    p = malloc[num];

}

void Test(void)

{   

    char *str = NULL;  

    GetMemory(str, 100);    // str 仍然为 NULL    

    strcpy(str, "hello");   // 运行错误   

    free(str);

}

=>此例中将指针str作为实参传给形参p,表示让指针p指向指针str所指向的地址空间。在函数GetMemory中为指针p新申请一块内存,其结果是让指针p指向新申请的内存地址,而这个做法并不改变指针str的指向,因此Test函数中运行完GetMemory之后str仍然为NULL。

这就如同下边的函数:

void GetMemory(char *p, int num)

{

   //进入这个函数后形参p指向实参地址

   char a = 9;
   p = &a;          //此处将p指向变量a的地址

}


五,

上述四中的例子不能申请内存,如果非要用指针申请内存可用指向指针的指针,或者三中的指针函数也行。

void GetMemory2(char **p, int num)

{

    //*p = new char[num];

     *p = (char *)malloc(num);

}

void Test2(void)

{

    char *str = NULL;

    GetMemory2(&str, 100);  // 注意参数是 &str,而不是str

    strcpy(str, "hello");

    //cout<< str << endl;

    printf("str:%s\n", str):

    free(str);

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值