fgets,优先级问题导致Segmentation fault

来源:互联网 发布:ds cloud windows 编辑:程序博客网 时间:2024/05/01 13:51

首先,看段代码

 

 1 #include <stdio.h>

  2 
  3 int main()
  4 {
  5     char buffer[BUFSIZ+1];
  6     FILE *fpin;
  7 
  8     if((fpin = fopen("test","r") == NULL))
  9     {
 10         printf("can't open test.\n");
 11         return 1;
 12     }
 13 
 14     while(fgets(buffer,BUFSIZ,fpin) != NULL)
 15     {
 16         if(fputs(buffer,stdout) == EOF)
 17         {
 18             printf("fputs error to pipe.\n");
 19             return 1;
 20         }
 21     }

 22 }

这段代码运行会产生段错误:Segmentation fault

经过调试gdb调试发现段错误是第14行代码处 fgets(buffer,BUFSIZ,fpin) 产生的。

这里的fpin 是 NULL。

在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的 
1)访问系统数据区,尤其是往 系统保护的内存地址写数据最常见就是给一个指针以0地址 
2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域 

所以再查找fpin 是 NULL的原因

仔细看第8行代码

if((fpin = fopen("test","r") == NULL))

因为 == 的优先级高于 = 且  ==号是左结合,=是右结合,所以这句话等价于

fpin = ( fopen("test","r") == NULL )  

即 fopen的返回值 与 NULL做 逻辑比较运算,将返回的NULL 复制给fpin,

所以这句话并没有起到检查fpin指针的作用

故第8行代码应该为

if((fpin = fopen("test","r"))== NULL)


运行结果正常:

zyx@zyx-Lenovo:~/Desktop/pipe$ cat test 
hello,aa!
the second line!
i know i can!
you can too!
zyx@zyx-Lenovo:~/Desktop/pipe$ ./segment 
hello,aa!
the second line!
i know i can!
you can too!


另附C运算符优先级表:

C语言运算符分类  1级优先级(左结合)   () 圆括号;[]下标运算符;->指向结构体成员运算符;. 结构体成员运算符。   2级优先级(右结合)   !逻辑非运算符;~按位取反运算符;++前缀增量运算符;--前缀减量运算符;+正号运算符;-负号运算符;(类型)类型转换运算符;*指针运算符;&地址运算符;sizeof长度运算符。   3级优先级(左结合)   *乘法运算符;/除法运算符;%取余运算符。   4级优先级(左结合)   +加法运算符;-减法运算符。   5级优先级(左结合)   <<左移运算符;>>右移运算符。   6级优先级(左结合)   <、<=、>、>=关系运算符。   7级优先级(左结合)   ==等于运算符;!=不等于运算符。   8级优先级(左结合)   &按位与运算符。   9级优先级(左结合)   ^按位异或运算符。   10级优先级(左结合)   |按位或运算符。   11级优先级(左结合)   &&逻辑与运算符。   12级优先级(左结合)   ||逻辑或运算符。   13级优先级(右结合)   ? :条件运算符。   14级优先级(右结合)   =、 +=、 -=、 *=、 /=、 %=、 &=、 ^=、 |=、 <<=、 >>=赋值运算符。   15级优先级(左结合)   ,逗号运算符。


原创粉丝点击