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;时,程序会崩溃。因为这个指针没有初始化,也没能从子函数内申请到内存空间,是指向未知位置的,所以会崩。。
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; }
4、为什么使用引用就可以解决问题了呢?
因为这个时候,编译器就不会在给参数p制作一个临时变量了,我们明确指出了这是一个副本(引用,其实就是被引用对象的副本),他在子函数执行结束的时候也就不会在被释放了。
以上内容,个人观点,欢迎指正。