我正在使用K&R的例子,它是一个cat工具来查看文件
#include <stdio.h> main(int argc,char **argv){ FILE *fp; void filecopy(FILE *,FILE *); if(argc==1) filecopy(stdin,stdout); else // accidentally mistyped while(--argv > 0) // should have been --argc > 0 if((fp=fopen(*++argv,"r"))==NULL){ printf("cat: can't open %s\n",*argv); return 1; }else{ filecopy(fp,stdout); fclose(fp); } return 0; } void filecopy(FILE *ifp,FILE *ofp) { int c; while((c=getc(ifp))!=EOF) putc(c,ofp); }
当用gcc cat.c编译,当我从terminal运行./a.out cat.c时,我得到的只是一些chinnesse符号和一些可读的文本(名字像_fini_array _,_ GLOBAL_OFFSET_TABLE_等等),而垃圾只是继续,直到我按Ctrl + C, 我想问为什么我没有Segmentation故障 ,因为没有程序正在从argv开始地址读取每个内存位置? 我不应该有权这样做?
我们来看看这两个连续的行:
while(--argv > 0) if((fp=fopen(*++argv,"r"))==NULL){
每当你减少argv
,你最终在下一行增加它。 总的来说,你只是递减和增加了argv
但你实际上从来没有读过argv
内存区域的边界。
即使您正在读取argv
内存区域的边界,这也是未定义的行为 ,并且不保证会出现分段错误。 你得到的结果取决于你的编译器,操作系统和其他程序。
我怀疑执行--argv
也给你未定义的行为,因为在执行该行之后,指针可能指向为argv
数据分配的数组之外。 但是,由于在指向那个时候你并没有取消引用argv
,所以原来是没问题的。