浅谈C语言内存
Posted -YIN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈C语言内存相关的知识,希望对你有一定的参考价值。
浅谈C语言内存
内存分配
在C语言中内存分别分为栈区(stack)、堆区(heap)、未初始化全局数据区、已初始化全局数据区、静态常量区(static)、代码区(data)。
(1)栈区(stack):存放函数,,形参和局部变量,以及函数调用开辟的栈帧;函数结束返回时自动释放空间。先进后出,向地址减小方向增长(由高地址到低地址)。
(2)堆区(heap):c语言中使用malloc、realloc、calloc等开辟的内存就在堆,从向地址增大方向增长(低地址向高地址)。由程序员手动分配释放的储存区,如果程序员不手动释放这块内存,内存将一直被占用,直到程序运行结束由系统自动收回。
(3)静态常量区(static):全局变量、静态变量(全局和局部静态变量),以及字符串常量(不能随意修改)。(const修饰的全局变量也储存在常量区,const修饰的局部变量依然在栈上。)
C语言内存示意图
栈
栈(Stack)是一种限定性线性表,是数据结构的一种,是将线性表的插人和删除操作限制为仅在表的一端进行,通常将表中允许进行插入、删除操作的一端称为栈顶(Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器来指示。同时表的另一端被称为栈底(Bottom)当栈中没有元素时称为空栈。栈的插入操作被形象地称为进栈或入栈,删除操作称为出栈或退栈。
因为C语言内存空间是有限的,堆栈相向而生,系统分配给栈的空间是有限的所以当函数调用达到一定量级(死循环,无限递归)时,可能导致一直开辟栈空间 最终发生栈空间耗尽,即栈溢出现象(stack overflow)。
斐波纳契数列
以斐波那契数列递归解法为例
int Fib(int n)
{
if (n <= 2){
return 1;
}
else{
return Fib(n - 1) + Fib(n - 2);
}
栈函数空间示意图
但当FIb()递归函数计算第45个斐波那契数时Fib(45),就会出现栈溢出现象导致结果出现问题,而且特别费空间和时间,所以这时出现的死递归便是递归问题的缺陷
解决方法:
(1):用非递归方法改写递归。
(2):使用static对象替代nonstatic局部对象(在栈上开辟),可以减少每次递归时对局部变量的产生和释放。
//完整斐波那契数列递归代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>
// //迭代方法
//int Fib(int n)
//{
// int num1 = 1, num2 = 1;
// int fib;
// while (n>2){
// n--;
// fib = num1 + num2;
// num1 = num2;
// num2 = fib;
// }
//}
//递归方法
int Fib(int n)
{
if (n <= 2){
return 1;
}
else{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int number;
scanf("%d", &number);
printf("%d\\n", Fib(number));
system("pause");
return 0;
}
欢迎大佬指教,如有错误感谢指正。
以上是关于浅谈C语言内存的主要内容,如果未能解决你的问题,请参考以下文章