关闭

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

发表于:2012-12-27 09:49

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:海 子    来源:51Testing软件测试网采编

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

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

  以下是各个区的作用:

  (1)代码区:存放程序代码;

  (2)数据区

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

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

  堆区:这部分存储空间完全由程序员自己负责管理,它的分配和释放都由程序员自己负责。这个区是唯一一个可以由程序员自己决定变量生存期的区间。可以用malloc,new申请对内存,并通过free和delete释放空间。如果程序员自己在堆区申请了空间,又忘记将这片内存释放掉,就会造成内存泄露的问题,导致后面一直无法访问这片存储区域。

  栈区:存放函数的形式参数和局部变量,由编译器分配和自动释放,函数执行完后,局部变量和形参占用的空间会自动被释放。效率比较高,但是分配的容量很有限。

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

  2)注意常量的存放区域,通常情况下,常量存放在程序区(程序区是只读的,因此任何修改常量的行为都是非法的),而不是数据区。有的系统,也将部分常量分配到静态数据区,比如字符串常量(有的系统也将其分配在程序区)。但是要记住一点,常量所在的内存空间都是受系统保护的,不能修改。对常量空间的修改将造成访问内存出错,一般系统都会提示。常量的生命周期一直到程序执行结束为止。

  在弄懂内存分配的问题过后,来看看函数调用的过程:

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

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

  内存分配的问题:

  int a=1;           a在栈区
  char s[]="123";    s在栈区,“123”在栈区,其值可以被修改
  char *s="123";     s在栈区,“123”在常量区,其值不能被修改
  int *p=new int;    p在栈区,申请的空间在堆区(p指向的区域)
  int *p=(int *)malloc(sizeof(int)); p在栈区,p指向的空间在堆区
  static int b=0;    b在静态区

  1、test1

#include<iostream>
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;
}

  第一行输出和第三行输出的结果相同,而第一行、第三行与第二行输出的结果不同。从这里可以看出,当指针作为参数进行传递时传递的也只是一个值,只不过该值只一个地址,因此对于形参的改变并不影响实参。

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号