(五十九)自动存储、静态存储、动态存储

自动存储:

函数内部定义的常规变量,被称为自动变量,这意味着他们在所属的函数被调用的时候自动产生,在该函数结束时消亡。

 

自动变量是一个局部变量,作用域为包含他的代码块,比如int main(){}中定义的int a; 在int abc(){}这个函数中就不能用。

 

自动变量通常储存在 栈 中,这意味着执行代码块时,其中的变量将依次加入到 栈 中,而离开代码块时,将按相反的顺序释放这些变量,这被称为后进先出(LIFO),因此,在程序执行的过程中,栈将不断的增大和缩小。

 

静态存储:

静态存储是整个程序执行期间都存在的存储方式。使变量成为静态的方式有两种:

①在函数外面定义他,比如:

#include <iostream>
using namespace std;
int a = 1;
int main()
{
	cout << a;
	system("pause");
	return 0;
}

②在声明变量的时候,使用static;如代码:

static int a = 1;

当使用static的时候,能使得函数在调用之后,再次调用的时候,static限定的值能保持在上次调用之后,函数的值。如代码:

#include <iostream>
using namespace std;
void ab();
int main()
{
	ab();	//调用函数ab
	ab();	//再次调用函数ab
	system("pause");
	return 0;
}

void ab()
{
	static int a = 1;	//在第一次起作用的时候a=1,后面再次执行的时候不会再次给a赋值为1
	cout << "调用ab函数的时候显示a的值:" << a << endl;
	a = a + 1;
	cout << "a +1 =" << a << endl;;
}

输出:

调用ab函数的时候显示a的值:1
a +1 =2
调用ab函数的时候显示a的值:2
a +1 =3
请按任意键继续. . .

 

我们发现,第一次执行函数ab()的时候,输出a的值是1,然后在执行函数的时候,a=a+1,于是a=2

当第二次执行函数的时候,a并不是值为1,而是保持了第一次调用函数ab()退出时变量a的值,即a=2。

这是static来限定函数内变量的特点,保持函数变量在退出时的值。

 

 

动态存储和内存泄露:

new和delete运算符提供了比静态变量和自动变量更智能的存储方式。

 

他们管理了一个内存池,这在c++被称为自由存储空间(free store)或堆(heap),该内存池与 用于 静态存储 和 动态存储 的内存是分开的。

 

使用new在堆 上面创建变量,然后再使用delete进行删除,可以避免内存泄露。如果单纯使用new,而没使用delete,那么将会导致new的内存地址被占用,在整个程序周期之内,就无法再次使用这部分内存了。在极严重的情况下,很可能导致内存被全部用尽,于是程序崩溃。例如代码:

#include<iostream>
char *getname(void);
using namespace std;

int main()
{
	int i;
	for (i = 1;i<5;i++)
	{
		char*a;
		a = getname();	//这个时候,指针c和指针a的指向内存地址是相同的
		cout << "在主函数里,把指针c的地址赋给指针a,指针a的值为" << a << endl;
		cout << "指针a的地址为" << (int*)a << endl;
		delete[]a;	//删除指针a,因为指针a和指针c指向的内存地址相同,相当于也delete了指针c
		cout << endl;
	}
	system("pause");
	return 0;
}

char*getname()
{
	char*b = new char[20];	//指针b占用了堆中的内存空间
	cout << "随便输点什么,别超过20个字符" << endl;
	cin.get(b, 20).get();
	cout << "你输入的是: " << b << endl;
	cout << "你输入的位置所在的内存地址为:" << (int*)b << endl;
	char*c = new char[strlen(b) + 1];	//初始化指针c,并位置new一个新的内存地址
	strcpy_s(c, strlen(b) + 1, b);
	cout << "将你输入的字符串复制到指针c的位置。" << endl;
	cout << "指针c的地址为:" << (int*)c << endl;
	cout << "指针c所指向地址的值为" << c << endl;
	delete[]b;	//因为指针c和指针a指向相同,在main函数中delete指针a,就相当于delete了指针c。
	//但指针b不同,如果不delete指针b,指针b所占用的内存空间就一直存在,于是就可能造成内存泄露

	return c;
}

因为在getname()函数中,new了2次。在main函数中new了一次,并delete了一次。

首先,main函数中的delete了main函数中new的,

又由于getname()函数中的指针c和main中的指针a相同,于是相当于又delete了一个getname()函数中的指针,但还存在一个指针b没有被删除,这个时候,只有删除了指针b,才可以避免导致内存泄露。

时间: 2024-10-28 22:25:22

(五十九)自动存储、静态存储、动态存储的相关文章

五十九、配置广域网中的Windows NT_网络冲浪

五十九.配置广域网中的Windows NT     Windows NT 4.0作为一个高性能32位多任务.多用户的网络操作系统,由于其界面的友好性和强大而直观的管理功能,无论对网络新手还是资深系统管理员,都可以迅速地构造起一套基于Windows NT的网络环境,从而赢得了众多用户的青睐.然而,随着用户网络节点的不断增加.挂接网段数的持续增长,使得网络规模日趋增大,一些在局域网环境中无法遇到的问题就会逐步地暴露出来.因此,如何保证Windows NT在多网段.多主域的复杂环境下,充分满足用户各种

超三百商家入驻五十九秒开放平台

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 国内首家电子商务效果营销平台五十九秒平台近日宣布,已与国内三百多家B2C商家达成合作协议,整合分析合作商家的销售数据,并将数据开放给合作网站及软件合作伙伴. 据了解,五十九秒平台已与国内三百多家正规B2C商家达成合作协议,整合了合作商家当前销售的商品数据,通过对数据深度挖掘.检索最终将数据以API接口的方式开放给五十九秒的合作网站及软件合作伙

五十九秒开放平台首开API 谁会第二家?

中介交易 SEO诊断 淘宝客 云主机 技术大厅 国内首家电子商务效果营销开放平台五十九秒(http://www.59miao.com)开放平台近日宣布,已与国内三百多家B2C商家达成合作协议,整合分析合作商家的销售数据,并将数据API开放给合作网站及软件合作伙伴. 该模式推出后,立刻引起业内广泛关注和讨论,然而现今的中国互联网中从来不缺乏模仿者.跟风者何时出现,现在还是个未知数.但可以预计的是,2012年随着电子商务的复苏,一定会有第二个"五十九秒".第三个"五十九秒&quo

拒绝“烧钱” 五十九秒引领电商迈入细致新营销时代

中介交易 SEO诊断 淘宝客 云主机 技术大厅 2011年初,当铺天盖地的团购信息从各种渠道飞速涌向我们的时候,很难料到这种情势会在年底演变成另一番景象--团购网站倒闭成潮.不再被资本青睐.不再被商家信任. 其实,这只是中国电子商务"虚火过旺"的一个缩影.过去两年风投向中国电商注资达300亿以上,大笔的"热钱"被电商们用来疯狂"烧钱"砸广告.抢人才,以致融到的钱短期内迅速"溜走",而后出现的裁员压缩成本.断臂求生实属无奈之举,

GOLIVE5.0教程(五十九)

教程 再下来,进入图9浮动框的Inspector面板后,在Name文本编辑框中指定当前浮动框的名称.当第一个浮动框被创建后,GoLive 5会自动为它分配一个名称:Layer1(图层1),对创建的第二个浮动框也会自动分配一个名称:Layer2,等等.该名称能在有多个浮动框存在的情况下,标识每一个浮动框,从而将它们作为有名物件来引用,通常老练的Web页面设计者会指定一个特定的.包含某种问意义的名称,如使用Plane命名该浮动框,意识就是说此浮动框将用于表现飞行中的飞机. 图9 调整屏幕上的各窗口位

Ruby on rails开发从头来(五十九)- ActiveRecord基础(预加载子记录)

预加载子记录讨论的问题和"延迟加载"是相同的.通常Active Record会推迟从数据库中加载子记录,直到你需要他们,例如,通过Rdoc中的例子,我们假定博客程序有一个Model,像下面这样: class Post < ActiveRecord::Base belongs_to :author has_many :comments, :order => 'created_on DESC' end 如果我们遍历所有的post,访问作者和评论属性,我们使用一个Sql查询来返回

(五十八)结构与指针

在使用new来创建动态结构时,表示创建的新结构中的某个变量,和普通结构中某个变量的形式不同.例如: #include<iostream> #include<string> using namespace std; struct ab //定义一个结构ab { string a; //名字 int b; //重量或数量 double c; //单价 }; int main() { ab *shuiguo = new ab; //声明结构水果(shuiguo),使用结构ab形式,通过n

内存机制-关于动态存储与静态存储的区别

问题描述 关于动态存储与静态存储的区别 什么时候要用到动态存储呢?它在用的时候还要指定大小,和静态分配区别在哪呢? 解决方案 运行的时候若由用户指定了一个大小n,程序接下来就可以这样分配int *arr = (int *) malloc ( sizeof(int) * n ); 解决方案二: 编译的时候无法确定大小的,只能用动态存储.另外,程序中可能使用,也可能不使用的存储,用动态存储可以提高性能. 解决方案三: 我是说编译时无法确定大小.而不是说无法确定大小.malloc中指定变量,而变量来自

十五款可以替代谷歌GDrive的云存储服务

据国外媒体报道,谷歌凭借它的搜索引擎成为IT领域鼎鼎大名的企业,它的智能手机操作系统(Android)和社交网络(Buzz network.Google+)都在各个领域最富盛名,此前,谷歌发布了云存储服务GDrive,eWEEK 总结了十五款可以替代谷歌GDrive的云存储服务. 亚马逊CloudBerry 亚马逊CloudBerry 是云服务"先驱"创造的最早的消费者存储服务,CloudBerry在线备份可以经亚马逊S3服务测试过的备份和恢复程序. Dropbox Dropbox是一