浅谈C++中内存分配、函数调用和返回值问题

  • 时间:
  • 浏览:0

int *p=new int;    p在栈区,申请的空间在堆区(p指向的区域)

执行结果是 hello world!

1.test1 

本文转载自海 子博客园博客,原文链接:http://www.cnblogs.com/dolphin0520/archive/2011/04/04/60 60 61.html如需转载自行联系原作者

注意:1)全局变量以及静态变量存放满静态数据区;

    堆区:这部分存储空间全部由多线程 池池员自己负责管理,它的分配和释放都由多线程 池池员自己负责。这些区是唯一那我前会 由多线程 池池员自己决定变量生存期的区间。前会 用malloc,new申请对内存,并通过free和delete释放空间。将会多线程 池池员自己在堆区申请了空间,又忘记将这片内存释放掉,就会造成内存泄露的疑问,愿因 上面总爱 无法访问这片存储区域。

int *p=(int *)malloc(sizeof(int)); p在栈区,p指向的空间在堆区

char *s="123";     s在栈区,“123”在常量区,其值不前会 被修改

3.test3  

执行某个函数时,将会有参数,则在栈上为形式参数分配空间(将会是引用类型的参数则类外),继续进入到函数体外部,将会遇到变量,则按具体情况为变量在不同的存储区域分配空间(将会是static类型的变量,则是在进行编译的过程中将会就分配了空间),函数内的话语执行时候,将会函数那末 返回值,则直接返回调用该函数的地方(即执行远点),将会位于返回值,则先将返回值进行拷贝传回,再返回执行远点,函数全部执行完毕后,进行退栈操作,将刚才函数外部在栈上申请的内存空间释放掉。

    2)注意常量的存放区域,通常具体情况下,常量存放满多线程 池池区(多线程 池池区是只读的,就让任何修改常量的行为全是非法的),而全是数据区。有的系统,也将部分常量分配到静态数据区,比如字符串常量(有的系统也将其分配在多线程 池池区)。随前会记住某些,常量所在的内存空间全是受系统保护的,不前会 修改。对常量空间的修改将造成访问内存出错,一般系统前会提示。常量的生命周期总爱 到多线程 池池执行结束了了英语 为止。

using namespace std;void test(void){ char *p=(char *)malloc(sizeof(char)*60 ); strcpy(p,"hello world"); free(p); if(p==NULL) { cout<<"NULL"<<endl; }}int main(void){ test(); return 0;}

C++编译器将计算机内存分为代码区和数据区,很显然,代码区就让我存放多线程 池池代码,而数据区则是存放多线程 池池编译和执行过程出現的变量和常量。数据区又分为静态数据区、动态数据区,动态数据区包括堆区和栈区。

4.test4

6.test6

输出结果为 1

   b.动态数据区:包括堆区和栈区

static int b=0;    b在静态区

int a=1;           a在栈区

using namespace std;int test(void){ int a=1; return a;}int main(void){ int b; b=test(); cout<<b<<endl; return 0;}

   a.静态数据区: 在编译器进行编译的时候就为该变量分配的内存,存放满这些区的数据在多线程 池池全部执行结束了了英语 后系统自动释放,生命周期贯穿于整个多线程 池池执行过程。

using namespace std;char* test(void){ char *p="hello world!"; return p;}int main(void){ char *str; str=test(); cout<<str<<endl; return 0;}

 在谈述函数调用和返回值疑问时候,先来看看C++中内存分配的疑问。

输出结果将会是hello world!,也将会是乱麻。

运行结果 hello world

char s[]="123";    s在栈区,“123”在栈区,其值前会 被修改

2.test2

在这里注意了,free()释放的是指针指向的内存!注意!释放的是内存,全是指针!这点非常非常重 要!指针是那我变量,不前会 多线程 池池结束了了英语 时才被销毁。释放了内存空间后,那我指向这块空间的指针还是位于!只不过现在指针指向的内容的垃圾,是未定义的,什么都有 说是垃圾。就让,释放内存后应把把指针指向NULL,防止指针在上面不小心又被使用,造成无法估计的后果。

5.test5



第一行输出和第三行输出的结果相同,而第一行、第三行与第二行输出的结果不同。从这前会 能看出,当指针作为参数进行传递时传递的也就让我那我值,只不过该值只那我地址,就让对于形参的改变固然影响实参。

同样返回的是指针,为那此这里会正确地打印出hello world1?这是将会char *p="hello world!",指针p是存放满栈上的,就让"hello world!”是那我常量字符串,就让存放满常量区,而常量区的变量的生存期与整个多线程 池池执行的生命期是一样的,就让在test函数执行时候,str指向存放“hello world!”的单元,随前会单元里的内容在多线程 池池那末 执行完是不要再被修改的,就让前会 正确输出结果。

有人会问为那此这里传回来的值前会 正确打印出来,全是栈会被刷新内容么?是的,人太好,在test函数执行时候,存放a值的单元是将会会被重写,就让在函数执行return时,会创建那我int型的零时变量,将a的值克隆好友拷贝给该零时变量,就让返回前会 够得到正确的值,即使存放a值的单元被重写数据,就让不要再受到影响。

using namespace std;char* test(void){ char *p=(char *)malloc(sizeof(char)*60 ); strcpy(p,"hello world"); return p;}int main(void){ char *str; str=test(); cout<<str<<endl; return 0;}

以下是各个区的作用:

    栈区:存放函数的形式参数和局部变量,由编译器分配和自动释放,函数执行时候,局部变量和形参占用的空间会自动被释放。数率单位比较高,就让分配的容量很有限。

using namespace std;void test(int *p){ int b=2; p=&b; cout<<p<<endl;}int main(void){ int a=10; int *p=&a; cout<<p<<endl; test(p); cout<<p<<endl; return 0;}

下面通过几条例子来谈谈内存分配和函数返回值的疑问:

内存分配的疑问:

出現这些具体情况的愿因 在于:在test函数外部声明的str数组以及它的值"hello world”是在栈上保存的,当用return将str的值返回时,将str的值拷贝一份传回,当test函数执行结束了了英语 后,会自动释放栈上的空间,即存放hello world的单元将会被重新写入数据,就让人太好main函数中的指针p是指向存放hello world的单元,就让无法保证test函数执行时候该存储单元上面存放的还是hello world,什么都有 打印出的结果有时候是hello world,有时候是乱麻。

这些具体情况下同样前会 输出正确的结果,是将会是用malloc在堆上申请的空间,这部分空间是由多线程 池池员自己管理的,将会多线程 池池员那末 手动释放堆区的空间,那末 存储单元里的内容是不要再被重写的,就让前会 正确输出结果。

(2)数据区

using namespace std;char* test(void){ char str[]="hello world!"; return str;}int main(void){ char *p; p=test(); cout<<p<<endl; return 0;}

   在弄懂内存分配的疑问时候,来看看函数调用的过程:

(1)代码区:存放多线程 池池代码;

那末 输出