传递动态内存

一、内存分配分类

1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。

3.从堆上分配,亦称动态内存分配。程序在运行的时候用malloc new 申请任意多少的内存,程序员自己负责在何时用free delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

二、传递动态内存

1.动态指针传递失败

 1 #include<iostream>
 2 using namespace std;
 3 void GetMe(char *p,int num)
 4 {
 5     p=(char*)malloc(sizeof(char)*num);    
 6 }
 7 int main()
 8 {
 9     char *str=NULL;
10     GetMe(str,100);
11     strcpy(str,"Hello!");
12     cout<<str<<endl;
13     return 0;
14 }

 

结果:程序运行奔溃,因为str还是为NULL,往空的地址强行赋值时,内存出错

原因:str并没有获取指针p开辟的空间。本质为调用函数 GetMe 时,函数会初始化函数内的局部变量,同时为传进来的实参str(指针和值都创建,引用除外)创建一个副本 _p,  _num,所以 p申请了内存,只是把p指向的内存地址改变,而str并没有改变,所以str依然没有获得内存。同时每次p申请的内存都不会得到释放,最终会造成内存泄露。

2.正确的传递动态内存

2.1  返回指针

 1 #include<iostream>
 2 using namespace std;
 3 char* GetMe(char *p,int num)
 4 {
 5     p=(char*)malloc(sizeof(char)*num);
 6     return p;
 7 }
 8 int main()
 9 {
10     char *str=NULL;
11     str=GetMe(str,100);
12     strcpy(str,"Hello!");
13     cout<<str<<endl;
14     delete str;
15     return 0;
16 }

结果:正常运行

原因:p申请了空间,并将该空间的地址作为返回值传给str,这样str就指向了p申请的内存空间

2.2 传递指针

 1 #include<iostream>
 2 using namespace std;
 3 void GetMe(char **p,int num)
 4 {
 5     *p=(char*)malloc(sizeof(char)*num);    
 6 }
 7 int main()
 8 {
 9     char *str=NULL;
10     GetMe(&str,100);
11     strcpy(str,"Hello!");
12     cout<<str<<endl;
13     delete str;
14     return 0;
15 }

结果:正常运行

原因:传递了str的指针给函数GetMe(),那么p就是str的地址的副本,地址的副本指向的内存是固定,所以该函数是为str地址指向的str开辟空间

 3.引用传递

 1 #include<iostream>
 2 using namespace std;
 3 void GetMe(char* &p,int num)
 4 {
 5     p=(char*)malloc(sizeof(char)*num);    
 6 }
 7 int main()
 8 {
 9     char *str=NULL;
10     GetMe(str,100);
11     strcpy(str,"Hello!");
12     cout<<str<<endl;
13     return 0;
14 }

结果:正常运行

原因:引用就是原传递实参的别名,地址相同,指向相同的地址空间

 

总结:实际上指针传递仍然是一种值传递,只不过在参数是指针的时候,传递的是指针的副本,这样在地址上的操作实际就反映到了内存中

 


 

posted @ 2018-10-03 23:11  louis-gx  阅读(176)  评论(0编辑  收藏  举报