| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3656 人关注过本帖
标题:C99的变长数组意义何在?
只看楼主 加入收藏
pycansi
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:5
帖 子:418
专家分:1060
注 册:2012-7-26
收藏
得分:0 
回复 10楼 TonyDeng
可是堆也有一样的问题e(检查用户输入),栈的话还能自动释放空间


莫问前尘有愧,但求今生无悔
2015-08-12 23:20
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用pycansi在2015-8-12 23:20:11的发言:

可是堆也有一样的问题e(检查用户输入),栈的话还能自动释放空间

现代的操作系统,根本就不怕内存泄漏,只要资源充足,程序可以撑到结束的时候(2G的进程内存空间,几乎等效于无限),到时系统会擦屁股,除非写的是服务程序永不结束的。何况正如你说,释放内存是程序猿的责任,但正确输入不是用户的责任,写一大段检测代码已经比free()一次消耗大多了。C没必要在这方面向解释语言靠拢。你说程序猿的责任,其实像scanf()/printf()这样类解释语言的机制,已经给程序猿带来无穷无尽的烦恼了,也不见有程序猿在用这些函数的时候能够有效防御无效输入。

[ 本帖最后由 TonyDeng 于 2015-8-12 23:34 编辑 ]

授人以渔,不授人以鱼。
2015-08-12 23:27
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
自动回收进程内存,在以NT为内核的Windows系统中已经没有任何问题(别的不知道),在以DOS为基础的Windows中的确不行(95/98即是此类系统)。实际上,内存管理问题,几十年来都没有绝对有效的好方法,GC是一种解决方案,但也是有代价的。不过,对一般的中小型程序来说,现在可算是不需过分考虑内存泄漏问题的时代了。

授人以渔,不授人以鱼。
2015-08-12 23:33
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
VLA应用在代码块内,越界即无意义,但实际上,一段代码块通常不超过30行,要在这样短的区间内记得free()一些东西,是很容易的。

授人以渔,不授人以鱼。
2015-08-12 23:47
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
当知道c的数组是在栈中开辟空间时,我就一直认为不能使用变长数组,所以第一次看到有人使用变长数组时觉得很奇怪,还是tony版主告诉我c99可以的(见识少啊)。
我当时是这样理解的:在函数中定义变量就是让编译器记住栈中的一个地址,比如我假设int长度为4,栈的初始位置为100,我定义“int i,a[5],j;”后,编译器会把地址97对应变量i,地址77-96对应数组a(&a[0]=77),地址73对应变量j,当编译器编译函数内其他代码碰到变量i、a、j时,一定会以这些已分配好的地址取代,这种编译方式高效精炼(没看过编译原理,不知道理解的正确否)。如果使用变长数组,问题就很明显,比如我在后面又使用了a[10],数组长度增加后,要不会覆盖变量j的值,要不就需要一个专门的内存管理程序来管理栈内存,这显然违背函数单一功能的本质,增加额外开销(堆就是系统管理的一大片内存,在堆中使用数据会降低运行效率)。
当然在栈有限的空间使用变长数组肯定也有tony版主说的不确定性造成内存泄漏的危险,不可取。

能编个毛线衣吗?
2015-08-12 23:49
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 15楼 wmf2014
VLA在确定下第一次空间之后,此后是不能变的,所以这不是真正的“变长”,准确地说就是“运行时再确定空间的数组”,别被那个字眼骗了。这种用法,除了在栈中分配空间之外,其余特性与堆申请没有丝毫区别,反而限制了所能申请的尺寸。

gcc就是仗着自己预设的栈有4M空间,才弄这个东西,但在微软这边,默认是只有1M。当然,大家都可以通过编译参数调整栈尺寸,那再大也没多大意义,总不会有人用到100M的栈,占用这么大栈空间的程序猿,一定脑子有毛病,他爱用递归。

[ 本帖最后由 TonyDeng 于 2015-8-12 23:56 编辑 ]

授人以渔,不授人以鱼。
2015-08-12 23:53
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我说过,C99就是gcc社区那一帮人操纵出来的标准,微软不尿它,所以C99的效果不好。C11出来之后,标准委员会解释过,这次是吸纳各家意见取得共识之后制订的,所以才会有微软的vs2013/2015支持C11的现象。标准不是自家玩的,是大家都愿意遵守和提供的协议,当有人不玩儿的时候,协议就无效,它又不是法律,拿它当神圣看,是傻的。最有用的,是实践,在自己的实践环境中用得好的,就用,没什么标准,不要强迫别人。像void main()这类,我一辈子不用gcc,又有何不可?!

[ 本帖最后由 TonyDeng 于 2015-8-13 00:04 编辑 ]

授人以渔,不授人以鱼。
2015-08-13 00:02
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我一直觉得,学编程的,应该有令狐冲的悟性才行,也就是我经常说的资质、天赋,不是单靠努力就可以的。分门划派,讲究气宗、剑宗区别,那是意气之争。若有人说那不过是小说,那么可以看看李小龙,他开创的截拳道,也是博采众家的,力图打破门派之别,一切以实战为宗。可惜大多数国人,都喜欢演绎套路,师傅教下的,就不敢稍有偏差,热衷中看不中用的花架子,还说南拳就不能用北腿,C++就不能用printf(),书上说用vc6,就不敢用vs2015,那不是呆子不知变通是什么。

[ 本帖最后由 TonyDeng 于 2015-8-13 00:19 编辑 ]

授人以渔,不授人以鱼。
2015-08-13 00:16
诸葛欧阳
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:流年
等 级:贵宾
威 望:82
帖 子:2790
专家分:14619
注 册:2014-10-16
收藏
得分:0 
回复 18楼 TonyDeng
看来T版要开山立宗啊

一片落叶掉进了回忆的流年。
2015-08-13 08:37
kenierlee
Rank: 6Rank: 6
等 级:侠之大者
威 望:3
帖 子:58
专家分:474
注 册:2015-7-28
收藏
得分:0 
以下是引用TonyDeng在2015-8-12 20:42:39的发言:

VLA的弊端和不切實際,放開棧溢出不談,光是把尺寸交給用戶這一點就已經很可怕,不用怎麼測試,想像一下敲入-1作為數組的尺寸時會怎樣,那可是位數全為1的數,數組尺寸容許多大的值,-1就有多大,32位機器無符號整數的最大值是32位全為1,你gcc有多大的棧去容納?發明這種東西還作標準用了。

還有那個可笑的main()函數必須返回整數,也是無稽之至,祗不過標準到如今都堅持而已。實際無聊就是無聊,不是因為權威這麼規定就神聖不可侵犯,VLA如此,main()的返回值也如此。

main的返回值不是进程的退出代码吗?如果不返回整数,进程的退出代码如何设置?
2015-08-13 09:28
快速回复:C99的变长数组意义何在?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030644 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved