编译没有分段错误

我正在使用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 ,所以原来是没问题的。