免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 6396 | 回复: 35
打印 上一主题 下一主题

字串指针和大字串越界问题之五问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-30 16:28 |只看该作者 |倒序浏览
嗯,看来我表达的有些问题,将问题重新说明一下。

第二次重编:
唉,发现自己的表达能力越来越差了,连话都说不明白了,到底是我变笨了,还是汉语太过博大精深了.......


问1,假设我定义 char *str_list = "fjsdlkfjeojlsfmle......."; 这样一直写下去,作为一个字符串,是否有长度的限制?最长能有多长?这个字符串是在GCC中定义的, 堆和栈的问题我倒没有考虑过,就安一般情况来吧,如果有朋友能弄清,也请说明一下。

答1:
原帖由 cunettenuc 于 2007-7-30 16:36 发表
1.当然有长度的限制, 长度的限制视具体的机器而定. 如果是堆上分配的空间的话, 一般不能大于2G. 至于栈上的, 我没有试过, 没有发言权, 但是肯定有限制.


答2:
原帖由 arnina 于 2007-7-31 09:40 发表
[quote]
结果是5771个!
也就是说栈的大小不能超过这么大了。
还有你那个定义如果是全局的话,情况又不同了,而且很难去测试了。


这位兄弟真强人,虽然那个测试程序我看不太懂

答3:
原帖由 cobras 于 2007-7-31 12:28 发表
C99标准中对字符串常量的长度有明确的限制,即,包括终止符在内是4192。
至于为什么要做这样的规定,我想是出于编译效率而非平台原因的考虑。

如果要实现无限长的字符串常量,编译器在编译时就必须使用某种动态内存机制来
保存不断变长的字符串,这样做可能不太有效率。我是这么认为的。


————————————————————————————————————————————————————————————

问2,如果我定义了一个字符串指针 char *p; 那么在我将一个超长的字串赋值给它的时候(这个超长的字串是有实际的值的,并非str_list[100]={0},可以将其看为 char *str_list = "fjslkfeiuof;lekaf......",用没有可能覆盖调内存空间中其他变量的值。这个指针就是通过 char *p;定义的,没有指定它的长度、大小等等。

答1:
原帖由 cunettenuc 于 2007-7-30 16:36 发表
2.首先如果你已经定义好了, 那么它的地址就确定了. 你拷贝给它的时候, 是在它合法的地址空间之内的. 当然不会覆盖其它变量的值. 但是如果你的长度很长的话,不见得你就能够分配成功.当然,如果你要赋给这个字符串的长度超过了它本来的长度,当然会覆盖掉其它的值.80年代著名的蠕虫病毒就是根据gets()这个函数来实现缓冲区溢出,然后进行攻击的.



————————————————————————————————————————————————————————————

问3,为了避免问2的情况,我想定义一个动态内存分配,下面的写法是否正确 char *p = malloc(sizeof(str_list));

答1:
原帖由 cunettenuc 于 2007-7-30 16:36 发表
3.char *p = (char*)malloc(sizeof(str_list));


————————————————————————————————————————————————————————————

问4,是否如同问3那样定义了动态内存分配之后就不会出现问2的情况了。

答1:
原帖由 baohuaihuai 于 2007-7-30 16:35 发表
拷贝字符串时应考虑到避免缓冲区溢出,如用strncpy代替strcpy.


这是一定的,不过还是没有说明是否会在内存中覆盖其他变量的值......
————————————————————————————————————————————————————————————

问5,Over.....呵呵

因为不常用,所以从来没考虑过这些问题,希望各位解答下

[ 本帖最后由 封神 于 2007-7-31 12:51 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-07-30 16:30 |只看该作者
问题都好有挑战性阿,楼下同志来吧

ps感觉1有点难度哦

论坛徽章:
0
3 [报告]
发表于 2007-07-30 16:35 |只看该作者
答1:字符串是什么概念?常量字符串?堆中的"字符串"?栈里的字符数组?先把这个弄清楚吧.
答2:根本就是错误的.你怎么能把字符串拷贝给指针呢?拷贝给数组或者动态内存还差不多.
答3:char *p = (char *)malloc(...);
答4:拷贝字符串时应考虑到避免缓冲区溢出,如用strncpy代替strcpy.

论坛徽章:
0
4 [报告]
发表于 2007-07-30 16:36 |只看该作者
原帖由 封神 于 2007-7-30 16:28 发表
问1,作为一个字符串,是否有长度的限制?最长能有多长

问2,如果我定义了一个字串指针 char *p; 那么在我将一个超常的字串拷贝给它的时候,用没有可能覆盖调内存空间中其他变量的值。

问3,为了避免问2的 ...



1.当然有长度的限制, 长度的限制视具体的机器而定. 如果是堆上分配的空间的话, 一般不能大于2G. 至于栈上的, 我没有试过, 没有发言权, 但是肯定有限制.
2.首先如果你已经定义好了, 那么它的地址就确定了. 你拷贝给它的时候, 是在它合法的地址空间之内的. 当然不会覆盖其它变量的值. 但是如果你的长度很长的话,不见得你就能够分配成功.当然,如果你要赋给这个字符串的长度超过了它本来的长度,当然会覆盖掉其它的值.80年代著名的蠕虫病毒就是根据gets()这个函数来实现缓冲区溢出,然后进行攻击的.
3.char *p = (char*)malloc(sizeof(str_list));
   需要将这个地址强制转换成char*指针. 至于后面的sizeof()的结果,只是一个长度而已.
4.不是很明白你的意思.
5.这是小弟的看法,如果有错误,请大家指正.谢谢.

论坛徽章:
0
5 [报告]
发表于 2007-07-30 16:45 |只看该作者
其实只要明白c的数组和指针的关系,这些问题就迎刃而解了!

论坛徽章:
0
6 [报告]
发表于 2007-07-30 16:51 |只看该作者

回复 #5 linux_ha 的帖子

很多人都清楚数组和指针的关系,但不见得都能回答第二个问题,愿闻其详,请回答超长后是个怎么赋值法,
比如
char array[120];
int i;//加上省得大家误会
char  *pa;
pa=array;
for (i=0;i<10000;i++,pa++)
*pa='a' ;// 把超过120个'a'赋给array时编译器如何处理?
请问 GCC是如何处理超长的?

[ 本帖最后由 cviolet 于 2007-7-30 17:07 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-07-30 16:56 |只看该作者
总觉得这几个问题能引伸出好多东西,当初看指针的时候是自学,好痛苦,整整看了3个多月,然后突然有一天就明白了,不过随着之后用的次数越来越多,突然又发现,自己什么都不明白。

PS:大家回答的时候还是直接把答案都说出来吧,不是人人都有那么高的认知的。有些特别的东西和知识也是没有地方去寻找的。

论坛徽章:
0
8 [报告]
发表于 2007-07-30 16:58 |只看该作者
原帖由 cviolet 于 2007-7-30 16:51 发表
很多人都清楚数组和指针的关系,但不见得都能回答第二个问题,愿闻其详,请回答超长后是个怎么赋值法,
比如
char array[120];
char  *pa;
pa=array;
for (i=0;i

自己试下就知道了.

论坛徽章:
0
9 [报告]
发表于 2007-07-30 16:59 |只看该作者
回6楼,问题2的重点是字符数组和指针赋值的问题,应该没有长度问题,因为只是把数组的地址赋给了指针变量,仅仅4个字节而已,何谈超出长度?
你说的是给一个既定长度的数组初始化时超出它的长度,应该是另外一个问题,这种情况编译器也没办法,不过编译器对栈的长度是有限制的,但这个限制不足以解决这个问题.over!

论坛徽章:
0
10 [报告]
发表于 2007-07-30 17:03 |只看该作者
整整看了3个多月
夸张了吧,我承认我挺笨的,可也就三天就看完了谭老师的书(有关指针的那章),不过我最近都天天上CU看贴。呵。。。
也在看<c解惑》要象你这么说的话,都没人敢学C语言了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP