2010年4月17日星期六
堆和栈的区别(转贴,作者为一c++程序员,具体姓名不清楚)
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—> 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—> 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—>全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束后由系统释放
4、文字常量区—>常量字符串就是放在这里的。程序结束后由系统释放
5、程序代码区—>存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上。
static int c =0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得来的和字节的区域就在堆区。
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。例如,声明在函数中一个局部变量int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。
2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程
序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是M(也有的说是M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便. 另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。
2.5堆和栈中的存储内容
栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,
程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
2.6存取效率的比较
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作
和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
2010年4月5日星期一
王江民:传奇一生
他,三岁因小儿麻痹症而落下终身残疾,没有进过正规大学的校门,二十多岁在一个街道小厂当技术员,三十八岁之前还不知道电脑为世间何物。就是这个无论从哪 个角度说,都从未受到社会眷顾的"弃儿",今天却被誉为中关村最富有传奇色彩的知识英雄,中国软件业界中的奇才,国际上都赫赫有名的"杀毒王"。他就是王江民。
王江民走出的人生第一步就非常沉重。他出生在山东烟台一个普通家庭,从记事起王江民就知道自己和别人是不同的,小儿麻痹症给他留下了一条病腿。他只能看着小朋友们在楼下尽情地欢呼跳跃。
王江民:我自己只能在家里的窗户上,在楼上看着楼下的人群。然后用一张纸撕成一些小条条,然后,拧成一些转转儿从楼上往下扔,看着转转儿一直飘到楼下去,小时候上小学的时候,比较喜欢学无线电搞半导体收音机。从矿石收音机一直到晶体管收音机,一直到双波段收音机,一直到无线电通迅,一直到电唱机留声机。这些东西我全都自己搞出来过。搞得还比较好也全都是自学的。
1971年他初中毕业,没有上过一天高中的他终于在一家街道工厂找到了工作。
那时候,王江民只是不满足于当工人,想当好一名技术员。凭借自己的刻苦和钻研,他改变了自己的命运,成为工厂里的技术骨干和革新能手。由于王江民在当地树立了身残志坚的榜样,还被授予了"全国新长征突击手标兵"、"全国青年自学成长标兵"、"全国自强模范"等诸多的称号。几年后,他被调到了一家国有企业,从事光机电设计和工控软件设计。
王江民:我最精通的就是机电行业。搞了几十项机电行业的新产品和技术革新。当然那些项目都很大,大机床、大设备都很庞大也非常地沉重。那么,后来就是慢慢大家对计算机时代的到来,开始有了一些认识。我那时候从纯机械到电子一直到电脑。因为我还不懂计算机呢。那时候我也没有学过,学校里也没有电脑,那时候我们国家经常有人出国回来后做报告说:国外电脑怎么着,说美国电脑怎么着、怎么着,以后整个社会整个工厂生产全都是自动化电脑控制的。把电脑都说神话了。那时候就感觉到。我是搞技术开发的,也许搞产品设计的也是搞技术的,如果不懂电脑就跟不上时代的潮流。我已经搞了十几年的机电技术,所以又开始学点儿电脑,那时候已经三十八岁。
就这样,38岁的王江民在不知不觉中开始了他人生旅途中的一项新的事业。很显然当时他自己并没有意识到。那时他的目的非常简单,就是学会使用计算机。
王江民:我自己开始学习电脑的时候,开始对电脑有初步认识的时候。是单位的一"IBM"。那么,现在想那个档次就是"186"。后来单位的电脑看得太死了,任何人不准动。学的时候还得偷偷摸摸去学几下,动不了几下让领导看见还得挨批评。那就是后来感觉到不方便,那怎么办呢?就干脆自己买一个。那时候刚刚社会上有一个"中华学习机"咱们国家第一批生产的电脑叫"中华学习机"。接着第二年就买了一个PC机也是国产的。
就是这位今天拥有正版用户最多、市场占有量最大的KV系列杀毒软件的发明人,有谁能够想到,当年王江民凭着自学的电脑知识,开发的第一个软件竟是被儿子逼出来的。
王江民:那时候,我儿子已经上小学一年级了。学校整天让家长出题,出的题也得符合逻辑。一天出五十道口算题,你不能说二加三等于几?二十加三十等于多少?你也得简单考虑它的逻辑性,也不能随便的出,应付,那不行。但是别看这五十道题,这五十道题出来后,你好好地考虑这五十道题,挺费事儿的。也挺费时间的。所以我干脆就编个程序通过计算机打印出来,然后一打印出来就几百道题、几十道题。
本来只是为了应付儿子,无意间却成为风靡全国的教育软件。在别人眼里,王江民是个天才。其实他只是个爱较真的人,每逢进入自己陌生的领域,他一定要刻苦钻研后征服;每逢遇到问题,他一定要归纳总结后解决。哪怕是不吃饭不睡觉。
王江民过去的同事严绍文:他是很多方面的专家,你看他是咱们国家的光学专家,可能他的专利到现在还没有多少人能超过他。他是光学专家、他是机械专家。我有时候觉得在我们这个小厂子,人家都说他是一个怪才。怎么王江民学什么他都行,学什么都比别人强。我觉得很奇怪呀!到我们这个(电脑)行业,我想肯定赶不上我了,其实他比我不知道强到哪去了。真是这样的。我觉得他最大的贡献可能就在这就是以前,在他研究之前做病毒的。也有但是都是有一说一,有二说二。他不是。他善于把这个问题总结起来,就是从具体的东西到一些抽象起来,这种东西我觉得这也是很可贵的事。
正是王江民这样的"较真",为他自己创造了一次又一次新的机遇,也让他离成功越来越近了。在工作中,他开始发现计算机老有病毒出来,影响设备的正常运行。
商人的嗅觉是最灵敏的。当王江民的杀毒软件从KV6迅速升级到KV100,一位电脑经销商跟王江民商量,你能不能别再送了,我帮你卖吧。一石激起千层浪,王江民的产品被卖到了中关村,杀毒软件KV100一炮打响。软件经销商们纷纷到山东向王江民申请许可经销权。
做技术出身的王江民初涉商海就被骗了,被他独家许可的这家软件经销商并没有兑现合约。虽然kv系列杀毒软件卖得很好,但是王江民没有拿到应得的转让费。
王江民:我就发现有些商人,他挣了那么多的钱。这点小钱他都不给开发人员。所以他也太奸滑了。商人也太不象话了,所以我的KV300就不再许可给他。觉得这种合作不长久。他赚了那么多的钱,到现在还欺骗我。我觉得他不是一个真正的合作伙伴,就不跟他合作了。
毫无疑问,众多的客户看好的是"江民"产品过硬的杀毒技术。但是,这过硬的技术也惹恼了假冒产品的仿制者和设计电脑病毒的人。他们开始用恶毒的手段攻击王江民。圈里人都知道中关村有过专门针对他的"倒王运动"。
中关村是创业者的硅谷,也同样是他们的麦城。因为无限的商机和激烈的竞争如影随形。书生气十足的王江民和他的公司在竞争中吃了不少亏,遇到明争暗斗的事他就气得拍桌子瞪眼睛。当别人问到他对某某人的看法,他会直截了当地说,"这个人不可交,我可不愿意理他。"接触他长了会觉得,他性格中很多地方不像商人,不够圆滑、不够狡诈。
王江民:按照我的性格我是学不会的。肯定是学不会的。我只有靠我们自己的技术,靠我们产品的技术含量,靠我们市场服务含量,来争取市场。来争取客户。但是这样可能比较累一些。
除了技术,王江民的信誉也是让他在商战中制胜的利器。就在对手以咄咄逼人之势蚕食杀毒软件市场之时,王江民推出了新一代杀毒软件KV3000。连邦公司一次性定货8万套,价值550万元。这相当于国内一流的通用软件公司全年的流水。这家公司做这笔生意,凭的就是王江民的信誉,他们认为王江民这三个字最值钱!王江民总结的商场原则是:做生意也跟做人一样,不能太贪。他给经销商的销售额分成经常超过经销商自己的想象。
王江民:其实我最喜欢做的还是开发软件。最喜欢做的是怎样把一个病毒去杀掉,就是说怎么样使你亲手做的软件,在整个社会上去杀那些计算机病毒。去拯救那些被计算机病毒侵害的计算机。最头疼的也就是说这个公司需要非常好的策划,出一个非常好的市场运作的方式、方法。怎么样去能把这个市场运作到最佳状态。但是这些都是说必须我去牺牲软件开发这一块。来纯粹作公司的管理,市场运作。但这一块还是我最不愿意做的。但是现在逼得我不做不行了。
在中关村科技园区企业百佳纳税名单中,江民公司是软件行业入选的5家之一,销售额在同行业中也名列前茅。靠着自己的技术和努力,王江民成为中关村的亿万富翁。有了钱,他没有过起奢华的生活,而是捐给了残疾人、教师和贫困的大学生。除了回报社会,他还为别人投资项目,虽然迄今为止他还没从这些投资项目里拿过分红。当然,王江民就是王江民,驰骋中关村六年,有时还是那么憨厚、那么单纯。
在中国的软件发展史上,王江民绝对是可圈可点的一个人。除了他的勤奋刻苦,他的成功从某种角度来说也是他做人的成功。在对大学生的演讲中,王江民总是不忘忠告:年轻人要少一些浮躁,多一些真才实学,要坚持勤奋学习,知识丰富了,能力高了,才能抓住机遇,机遇有的是。
FlowerCode@cnBeta 节选自 BTV
2010年4月2日星期五
杂记
原本有8人报名,3人中途退出,我跑了35分钟,被第一超了2圈,的确是loser。
操场上,一张张笑脸,给其他参赛的朋友加油的声音,和我都没有什么关系。我所做的,是平平淡淡,以相同的速度,跑出下一步。
第一次过计时点,听到说还有12圈,觉得有点好笑,又有点无奈,难道terminal才是真正的开始?
顶着风,看着周围所有陌生的面庞,逐渐想到最近正在做的Win32 SDK。同样陌生的函数,陌生的形式,都是过客。或许我才是过客,而他们并没有改变。
阳光格外的好,一切都是如此vivid。被灌的每一圈,都给对手一个大拇指——其实不存在竞争,大家都在获取自己的体验。
操场人逐渐减少,剩下的路程也越来越少。除了我外所有的朋友都有人递水鼓励,我耸耸肩,也许平平淡淡才是真的,因为自己一直在和自己同行。
第十圈时,原先在跑道的朋友开始和他的观众离开操场了。我依旧以相同的步幅,迈向那个逐渐只剩下工作人员的terminal。
等我到了terminal,耸耸肩,对不起,让各位久等了。从地上捡起外套,披在身上也离开操场了。
回到寝室,背上书包,走向教2时,才意识到,根本不存在什么terminal,因为路是无限延伸的。