关于字符数组的越界问题

xidianxiancai 2009-01-07 09:54:30
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main()
{
int x = 3;
char pa[]="/usr/";
printf("%d %d\n", &x, pa);
printf("%d\n",x);
strcat(pa,"abcdeabcdeabcdeabcdeabcde");
printf("%d\n",x);
getch();
return 0;
}
在vc下运行的结果如下:
1310588 1310580
3
1650550116
很明显,通过观察就能知道pa这个字符数组已经越界了。可是在VC中可以编译通过,而且输出strcat后的结果来。很奇怪,既然都有问题了,为什么还会输出结果?然后用什么样的方法来判断pa已经越界了(因为程序照常运行没问题,编译的时候无法告知越界的错误)?
我用的方法是:定义了个变量x,运行后,发现前后对x输出的结果会不一样。这样是不是就是说已经证明了该数组越界了,把x所在位置的内容给覆盖了,导致第二个printf对x输出的是一个随机的值。不知道我的方法是否可行?不知道还有别的方法没?
请指教。谢谢!
...全文
293 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰Ivan 2009-01-09
  • 打赏
  • 举报
回复
编译器的问题,你用gcc试试,如果数组越界会出段错误
lsd1025 2009-01-07
  • 打赏
  • 举报
回复
写的时候就留点心吧!
lpcii 2009-01-07
  • 打赏
  • 举报
回复
还是要养成好习惯吧,只要用了char[],就要牢牢记住它的大小
我建议应该把char pa[] = "abc"改成
char pa[4] = "abc".
尽量不要用这种默认的东西
jcwKyl 2009-01-07
  • 打赏
  • 举报
回复
不过你的方法始终是一种比较微妙的方法。大家都不知道的方法不建议在程序中使用。另外再补充一点你的方法,不需要一个int,一个char就行,int有时候检测不到,比如只越界了不到4个字节,你的int就检测不到,另外,初始值也非常关键,你不能保证溢出的内容一定不是你的x的初始值。最好是定义一个char类型的x,初始值为0,因为字符串的结尾都需要一个0的,如果检测到操作后的x的值为0,则大可放心,因为无论如何这都说明字符串在正确的位置以0结尾了。否则,肯定是溢出了。
这只是对你的方法的一点想法,程序员应该尽量写出安全的代码,不要依赖编译器和灾难后的恢复。
jcwKyl 2009-01-07
  • 打赏
  • 举报
回复
写代码判断越界感觉没有什么意义,因为都已经越界了,就算判断出来还能做什么。一般都是尽量预防越界的发生,如果要预防的话,方法就挺多的,比如微软新提供的一套字符串操作安全的函数等,或者用c++的string等。你用的方法当然可行,不过还是那样,预防胜过挽救。如果使用你的方法的话,有一个小建议,你可以把它们封装起来,如:
struct SafeStr {
int x;
char data[10];
};
这样的话一个x和一个字符串绑定起来。如果做更好的封装,直接用C++在这方面的常用方法。
ckt 2009-01-07
  • 打赏
  • 举报
回复
你要使用数组,就有责任保证其不越界.
对数组操作时可使用一些较为安全的函数,
如_snprintf,strncpy,strncat等.
baihacker 2009-01-07
  • 打赏
  • 举报
回复
在这点上c缺乏安全检查,因为数组在退化为指针的时候失去了一些信息.
这和C语言当初的设计初衷是有一定的关系的.
否则的话,每次访问都要检查?

这点你要在用户上来保证了,不能总依赖于编译器的.
lann64 2009-01-07
  • 打赏
  • 举报
回复
不是方法可不可行的问题,而是效率问题。根据具体情况自己找个平衡点。
多数情况下,程序里不是判断是否已经产生越界,而是事先判断,从而保证不产生越界。
jiangnanyouzi 2009-01-07
  • 打赏
  • 举报
回复
我个人觉得,这个问题的本身,是代码运行的时候,数组里面没有附加任何信息,比如int a[30];
当编译时候,编译器就化成类似于如下的语句:sub esp, 30 用来开辟30的字节给数组a,但是,
当运行时候,a的前后并没有任何特殊的标记来说明其边界(也就是楼上所说的没有类型检查),
其实,对于c语言的运行来说,所有的数据都是一样的,没有任何差别,这也是出于效率的考虑。
xiaoyisnail 2009-01-07
  • 打赏
  • 举报
回复
up
发现lz的代码就是我昨天给你的说明strcat不安全的例子。。。
编译器无法检测这个问题,要靠程序员自己注意,否则也不需要用更安全的如strncat来代替strcat
yellowhwb 2009-01-07
  • 打赏
  • 举报
回复
对指针,数组操作就是这样,不要都指望编译器或者运行时帮你检查,不然,去用java,C#好了!
sailing0123 2009-01-07
  • 打赏
  • 举报
回复
这里涉及到内存,
越界后明显影响了别的内存空间,
这种错误最难发现了!

程序中要坚决避免!

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧