读书人

C语言内存储器分配及函数返回值的解析

发布时间: 2012-08-02 11:35:25 作者: rapoo

C语言内存分配及函数返回值的解析。

C语言的内存分配主要如下:

(1)栈区:在执行函数时,函数内局部变量(不包含static变量)、函数返回值的存储单元在栈区上创建,

函数执行结束时这些存储单元自动被释放。栈区内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

(2)堆区:即动态分配内存分配,程序在运行时用malloc(calloc,realloc等)申请的内存,程序员自己负责用free释放内存。

(3)静态存储区:该内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。此处存放全局变量、static变量。

(4)常量区:整型常量、浮点型常量、字符型常量及字符串常量都分配在文字常量区,程序结束后由系统释放。

(5)代码区:存放整个程序的代码。数据和代码是分开存储的。

C语言内存储器分配及函数返回值的解析

C语言内存储器分配及函数返回值的解析

如下有几种容易出错的情况:

下面简单分析一下。

对于子函数char* function()。

内部分配了



返回的是b。是一个指向指向字符的指针。

修改一下function()

这个很好解释。a是数组名,就是一个指针,是一个执行含有两个char元素的数组的指针。

但是传过去的还是一个字符。

再改一下:


看,并没有传过来,是因为return a 中的a是局部数组的首地址,它是栈区地址。funciton函数执行结束时组数a存储单元自动释放。所以不应该返回过去。如果想要正确返回组数a的地址,可以再定义数组时加static修饰或定义为全局变量。

看结果:

C语言内存储器分配及函数返回值的解析

至今为止没有使用malloc。其实这个也可以达到这个结果。但是不能忘记free。

看如下程序:

不是说“函数执行结束时这些存储单元自动被释放。”么?

没关系我们再修改一下:



两个子函数,形参、返回值、函数体出了存储在静态区的常量不同其他都一样。

所以进入子函数时,系统为之分配的栈空间一样,再因为操作系统和编译器都一样。外部环境很相似。所以栈的地址区域和所有变量的分配地址都一样。

我们这里再说明一下:

(1)我们是在xp操作系统上运行的。是有MMU的。是有内存映射的。所以我们的地址这时都是虚拟地址,是操作系统为每一个

进程分配的4G的虚拟地址,通过内存映射这些地址会被映射到物理地址上。

(2)当第一个自函数退出时,为之分配的栈空间就会被释放。但并不是清零的操作,而是这块内存标明可以被使用,

在学习操作系统的过程中,还记得内存分配的。是沿着那个链表式的东西在找一块儿合适的内存空间。

被释放只是说明这块儿内存可以被重新分配。没有清空的操作,这个对比试验可以得出这个结果。

看程序:

子函数中初始化了一个字符数组,一个char指针,一个指向字符的char指针。结束前把这些局部变量的地址都传给了全局变量。

在主函数中,访问这些地址,都未成功。这是因为在函数结束后和打印变量之间还有其他函数的调用。所以,那块栈空间又被改写了。

注意,为了安全,在子函数中千万不要return 指针类型的局部变量值。栈内地址不能安全的传递到函数外。可以传,但是不安全,因为很肯能会改变。

1楼rohsuton昨天 08:56
”存储单元自动被释放“并不意味着存储单元的内容清空吧,这块内存没再次被使用的情况下可以使原来的数据吧

读书人网 >C语言

热点推荐