浅谈C++中的内存管理(一)

摘要:

  大家都知道变量的生存周期这个概念,可是有的时候变量生存周期已经结束,但是所分配的那块内存空间还是存在的。文章举了四个不同的例子,来说明这其中的原因。

  前言:
width="360" scrolling="no" height="300" frameborder="0" align="right" src="http://www.chinabyte.com/tag/cont_flash_software.html" marginheight="0" marginwidth="0">
  前一段时间在一个好友的的博客论 坛上看到他学习C++时遇到的一小点问题,是关于C++中最基本的内存分配方面的。其实对于内存这东西,除了知道我自己用的是256M的内存以外,我也不 太清楚他到底里面是怎么工作的。看了大师们的讲解,我深有体会,把这些讲解整理出来,为所有C++的newbie们共勉!

  正文:

  事情是因为这样一小段程序而来的。

int main()
{
  int i=10;
  int *j=&i;
  if(!0)
  {
    int l=20;
    int *k=&l;
    j=k;
    k=0;
  }
  cout<<*j;
  return 0;
}

  不用编译器,大家想想执行过之后应该打印什 么结果?我想大家的第一反应应该是打印出一个不确定的数。理由是在if语句里,我们定义了k这个变量,在if执行结束之后,这个变量k所占据的内存是被系 统收回的,于是也就造成了变量j所指的结果非常不确定。当然,如果编译并且执行过后,我们发现事情并不是像我们想象的那样,程序最终的打印结果是20,并 不是我们期待的一个不确定的数。下面就让我们分析一下原因吧!

  我们用debug的方式来一步一步的分析,在watch的窗口下输入里面所有的变量。

int i=10;  //i is 10 and &i is 0x0012ff7c
int *j=&i; //*j is 10 and &j is 0x0012ff7c
      //显然可以看出此时两个变量指的是同一地址
if(!0)
{
  int l=20; //l is 20 and &l is 0x0012ff74

  /*地址0x0012ff7c—0x0012ff75被占据。要说明的是,
  这个数值很有可能因为电脑硬件的不同而不同。*/

  int *k=&l; //*k is 20 and &k is 0x0012ff74

  //变量k与l指向同一地址。

  j=k;  //j is 0x0012ff74 and *j is 20

  /*指针间的赋值,这个语句的意思是把k指向的地址负值给j。
  此时这两个变量指向的是同一个地址,都是0x0012ff74,而那
  块地址存放的是20,所以也就有*j是20的原因。*/
}

cout<<*j; //*j is 20 and j is 0x0012ff74

/*此时同时可以看到k的地址是0x00000000,说明k这个变量
已经被自动销毁,所以地址指零。但是j所指的并不是k,而
是k所指的那段地址0x0012ff74,而由于此时j的生存周期还
没有结束(j是在if意外定义的),所以j指向的这块地址并
没有被收回,也就保存下来20这个数了。*/

  至此,我们分析完了程序的全过程的内存分配情况,最终结果是这样的。(图1)



  我们同时也可以在Memory里面看看这个地址的具体内容。我们可以看到是14,这是十六进制的数,化成十进制,正好是20。(图2)



  现在大家应该对上面那个程序的执行过程有一个大概地了解了吧!不过这个还不是我们想要得到的结果,我们需要的是打印一个不确定的结果。有了以上的分析,我们开始新的程序,让他打印出我们想要的东西。

  对于上面的程序,我们需要改动的是令变量j指向一个地址被释放的位置。于是就有了下面的程序。

int * foo()
{
  int l=20;
  return &l;
}

int main()
{
  int i=10;
  int *j=&i;
  j = foo();
  cout<<*j;
  return 0;
}

  编译器很“聪明”,编译后会给出一个警告。原话是“returning address of local variable or temporary”,指向的是上面程序的第四行,也就是return &l;这条语句。那句英文的意思也不用我再多解释了,相信大家都能看得明白。

  执行的结果,在debug下,是20;在release下,结果是4198795。显然那部分内存被释放掉了。这是因为在debug的程序里 面,执行完函数foo,并没有立即释放掉l的那个地址(目前我不清楚这句话说得是否精确)。在这个程序的release版本中,显然程序释放了那部分的地 址,所以指向了一个不确定的数。

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值