1.当数据超出了类型的最值或者有符号数被解析成无符号数时,可能会发生溢出。整型溢出的形式有:(1)存储溢出(2)运算溢出(3)符号导致的溢出
对于存储溢出,假如
int m=0x1000;
char n=m;
printf(“%d\n”,n)
结果会输出0,因为m占据4个字节的存储空间,而n占有一个,m赋值给n时,仅仅把最低字节给了n。
对于运算溢出,假如
unsigned char a=255;
unsigned char b=a+1;
printf(“%d\n”,b)
无符号字符型的数据最大为255,如果a+1,则会溢出,程序输出0.
对于符号导致的溢出,写程序:
int a[5]={1,2,3,4,5}; # define NUM sizeof(a)/sizeof(a[0]) int main() { int d=-1; if(d<NUM) printf("d is less than NUM"); else printf("d is not less than NUM"); return 0; }
程序的输出结果是 d is not less than NUM,因为在NUM是无符号整型的数据,d在与其比较时d被提升为无符号整型,变成了一个很大的整数。
整型溢出可能导致死循环,内存分配错误等,如
int *a=(int *)malloc(N*sizeof(int)),如果N是个很大的数,N*sizeof(int)会导致溢出,最终a指向的内存块远小于程序员要求的大小,这会引发错误甚至系统攻击。
防止整型溢出,在编码时尽量不使用无符号整型,使用有符号整型类型的变量,不用担心负数被编译器解释成很大的整数,会让程序更加安全。
2.判断整型溢出
对于无符号数的加法,判断整型溢出,可以这样:
void fun(unsigned int a,unsigned int b) { if(a>UINT_MAX-b) //UINT_MAX为无符号整型的最大值,在VC编译器中为0xffffffff { printf("overflow\n"); return ; } else printf("%d\n",a+b); }
对于无符号的乘法,可以这样判断溢出:
void fun(unsigned int a,unsigned int b) { if(a>UINT_MAX/b) { printf("overflow\n"); return ; } else { printf("%d\n",a*b); } }
对于有符号数的加法运算,判断溢出的方法与无符号数类似,但要考虑符号问题:
void fun(int a,int b) { if(a>0&&b>0&&a>INT_MAX-b) //INT_MAX为有符号整型的最大值,VC编译器中为2147483647 { printf("overflow\n"); return ; } if(a<0&&b<0&&a<INT_MIN-b) //INT_MAX为无符号整型的最小值,VC编译器中为-2147483648 { printf("overflow\n"); return ; } else printf("%d\n",a+b); }
原文:http://blog.csdn.net/u011608357/article/details/24552747