什么是整数溢出(整数溢出问题)
导语:整数溢出
如果一个整数用来计算一些敏感数值,如缓冲区大小或数值索引,就会产生潜在的危险。通常情况下,整数溢出并没有改写额外的内存,不会直接导致任意代码执行,但是它会导致栈溢出和堆溢出,而后两者都会导致任意代码执行。由于整数溢出发生之后,很难被立即察觉,比较难用一个有效的方法去判断是否出现或者可能出现整数溢出。
关于整数的异常情况主要有三种:(1)溢出,只有有符号数才会发生溢出。有符号数的最高位表示符号,在两正或两负相加时,有可能改变符号位的值,产生溢出。溢出标志OF可检测有符号数的溢出;(2)回绕,无符号数0-1时会变成最大的数,如1字节的无符号数会变为255,而255+1会变成最小数0。进位标志CF可检测无符号数的回绕;(3)截断,将一个较大宽度的数存入一个宽度小的操作数中,高位发生截断。
我们先来看有符号整数,这一类整数用于表示正值、负值和零,范围取决于为该类型分配的位数及其表示方式(原码、反码、补码)。当有符号数的运算结果不能用结果类型表示时就会发生溢出,可以分为上溢出和下溢出两种。
无符号数的运算是永远不会溢出的,它就像钟表一样无限循环,到达最大值的时候也就是回到了最小值,我们把这种现象叫作回绕,因此一个无符号整数表达式也永远不会得到小于零的值,如下所示。
下面是两个加法截断和乘法截断的例子。
整数转换是一种用于表示赋值、类型强制转换或者计算的结果值的底层数据类型的改变,这种转换可能是显式的(通过类型申明转换)也可能是隐式的(通过算数运算转换)。如果具有某个宽度的类型向一种具有更大宽度的类型转换,通常会保留数学值,但如果反过来,就会导致高位丢失,例如把一个unsigned char加到一个signed char上。具体来看就是下面两种错误:第一,损失值,当转换为一种更小宽度的类型时会损失值;第二,损失符号,从有符号类型转换为无符号类型时会损失符号。
其中,整型提升是指当计算表达式中包含了不同宽度的操作数时,较小宽度的操作数会被提升到和较大操作数一样的宽度,然后再进行计算。如下所示。
本文内容由快快网络小樊创作整理编辑!