小议内存

先看一个程序:
#include <stdio.h>
char *f1()
{
char a[]="Hello,world!";
return a;
}
char *f2()
{
char *a="Hello,world!";
return a;
}
void main()
{
char *s1;
char *s2;
s1=f1();
s2=f2();
puts(s1);
puts(s2);
}
看下结果:
预期结果1
 
f1乱码了,f2是正常的,为什么呢?
 
 
先看一下一个程序是怎么使用内存的:
预期结果2
一个程序在内存中,按照内存地址从低到高的顺序,分布着代码段、常量段、数据段、堆内存和栈内存
 
代码段用来存放程序的机器码
常量段用来存放所有的字符串常量
数据段用来存放全局变量和静态变量(这个段在程序加载后自动清0,这就是为什么全局变量和静态变量的初始值都是0)
代码段、常量段和数据段内存都是和程序的生命周期相同的,只有程序结束后,该内存才会被释放
 
堆内存,程序中用malloc等内存分函数申请的内存块,从数据段顶端开始,从低地址向高地址分配。必须调用free等内存释放函数,将不使用的内存释放。
栈内存,存放函数内的临时变量,程序每进入一个函数前,从栈内存内分配一块内存,大小等于该函数内的临时变量的大小,当函数结束后,该内存被自动释放。栈内存从高地址向低地址方向分配。
堆内存和栈内存在被分配出去后是不会重新初始化的,所以分配的时候内存中放的什么数据,你得到的内存中就是什么数据。这就是为什么临时变量和malloc的内出中的数据是随机值的原因。
 
下面我们来看看前面提到的几种情况:
1 . char a[] = "Hello world!";
a是局部字符数组变量,数组大小为13,数组内的元素被初始化为"Hello world! /0"。
a被存储在函数f1的栈内存中,return a将a的首地址返回回去了。f1函数结束后,f1的栈内存被释放,原来a所在的内存地址可能被挪做它用,所以那个地址里面放的是什么东西不得而知,因此puts输出该地址中的内容得到的结果是随机的。
  2. char *a = "Hello world!";
a是一个char*指针变量,大小为4个字节,其值是"Hello world!"这个常量字符串的首地址。"Hello world!"常量字符串被保存在常量段,不能被更改。
a被存储在函数f1的栈内存中,return a返回的是指针a的值,即"Hello world!"常量字符串的首地址。f1函数结束后,a被释放了,但a指向的常量段的内容没有变。因此puts输出是正确的。
 
3. static char a[] = "Hello world!";
a是静态字符数组变量,数组大小为13,数组内的元素被初始化为"Hello world! /0"。
a被存储在数据段内,return a将a的首地址返回回去了。f1函数结束后,a所在的内存不会被释放,因此puts输出该地址中的内容得到的就是a中存储的字符串。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值