C程序的内存分配

原文:http://tanghao0730.blog.163.com/blog/static/164247135201051153152371/

C中内存分配有三种方式

【1】静态存储区分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量、static静态变量。

【2】在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动释放。

【3】从堆上分配。也称动态内存分配,在程序运行时用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放。生存期由程序员决定。

在进行C/C++编程时,经常需要操作的内存可分为以下5个类别。

1:栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等。

2:堆区(heap):由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。

3:全局区(静态区)(static):存放全局变量、静态变量和常量。全局变量和静态变量的存储在一起的。程序结束后由系统释放。

4:文字常量区:常量字符串就是放在这里,程序结束后由系统释放。(文字常量区就是数据全局区?)

5:程序代码区:存放函数体的二进制代码。

参考参考《程序员面试宝典》p68一个题目。

char *strA()

{

 char str[ ]="hello world";

 return str;

}

首先要搞清楚char str[ ]="hello world"和char *str="hello world"这两者的区别。书上说char str[ ]="hello world"分配的是一个局部数组;char *str="hello world"分配的是一个全局数组,可以再深入阐释一下:

char *str="hello world" ,函数的局部变量只占了4个字节,因为它只声明了一个指针,该指针存于栈区,而"hello world"字符串内容是存放于文字常量区的,指针str就指向了这个常量区。比如"hello world"被编译器分配到0x2000到0x2011这段长度为12的内存区里,那么char *str="hello world" 语句运行时就相当于 char *str=0x2000。

char str[ ]="hello world",函数的局部变量分配了12个字节,该语句相当于char str[10]={104,101,108,108,111,32,87,119,111,114,108,100};字符串的内容时直接放在函数用的内存里边。

回到之前的题目,可知str里存在的地址是函数strA栈帧里"hello world"的首地址,但是在函数调用完成,栈区自动释放,栈帧回到调用strA之前的状态,return str无法得知当前栈区状态,所以程序无法输出正确结果。

可修改如下:

const char *strA()//定义为const型,限定变量不允许被改变。

{

 char *str="hello world";

 return str;

}

或者

const char *strA()

{

 static char str[ ]="hello world";  //str被定义为static,函数结束之后不释放,保留当前栈区状态。

 return str;

}

//===============================================

我自己加了一个例子,经典例子

#include <stdio.h>

int main (void)
{
 char str1[] = "abc";
 char str2[] = "abc";

 const char str3[] = "abc";
 const char str4[] = "abc";

 const char *str5 = "abc";
 const char *str6 = "abc";

 char *str7 = "abc";//虽然没写const,但其实和5,6是一样的
 char *str8 = "abc";
 printf("%d/n",( str1 == str2 ));
 printf("%d/n",( str3 == str4 ));
 printf("%d/n",( str5 == str6 ));
 printf("%d/n",( str7 == str8 ));
 printf("%d/n",( str5 == str8 ));
 printf("%s/n",str5);
 str7[1]='X';  //想换成aXc,没门!abc存在字符常量区,是常量,不可更改
 printf("%s/n",str5);
 return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值