内存的分配方式有几种? 动态内存的的传递注意事项!

1、内存的分配方式分为   静态存储区、栈、堆。

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

栈:在栈上创建,在函数(main函数或其他子函数)执行期间,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动释放。所以我们不能返回在函数内部定义的变量(函数内定义的指针可以返回),因为他们在函数执行结束时已经被销毁了。处理器的指令集中有关于栈内的分配运算,因此效率很高,但是分配的内存资源有限。

堆:从堆上分配,亦称为动态内存分配,使用new或malloc等申请任意多内存,程序员自己决定何时释放内存,使用灵活,问题也经常出现在这里。

2、动态内存的传递:

首先,子函数内不能返回出指针之外的其他变量,http://www.cnblogs.com/audi-car/p/4753292.html

其次,调用子函数时,编译器默认情况下,会自动为参数列表的每个参数制作临时的变量,这些临时变量的改变并不能真正传回到主函数内,且这些临时变量会在函数调用结束时,自动销毁(动态申请的内存除外,它不会销毁)。所以靠他们来实现参数或者内存的传递纯属扯淡。

最典型的例子,就是比较基础的swap()函数,还有下面这个例子:

void getMemory(char *p)
{
    p=new char[10];
}

int main(int argc, char **argv)
{
    char *str=NULL;
    getMemory(str);
    //char *str=new char[10];
    cout<<str<<endl;
    return 0;
}

在执行cout<<str<<endl;时,程序会崩溃。因为这个指针没有初始化,也没能从子函数内申请到内存空间,是指向未知位置的,所以会崩。。

image

3、怎么解决第2步的问题?

很简单,用引用就可以解决了

void getMemory(char *&p)    //使用引用
{
    p=new char[10];
}

int main(int argc, char **argv)
{
    char *str=NULL;
    getMemory(str);
    //char *str=new char[10];
    cout<<str<<endl;
    return 0;
}
image

4、为什么使用引用就可以解决问题了呢?

因为这个时候,编译器就不会在给参数p制作一个临时变量了,我们明确指出了这是一个副本(引用,其实就是被引用对象的副本),他在子函数执行结束的时候也就不会在被释放了。

以上内容,个人观点,欢迎指正。

原文地址:https://www.cnblogs.com/audi-car/p/4762845.html