13.5缓冲区溢出和下标错误

缓冲区溢出和下标错误是最常见的危险C程序中的错误。它们导致未定义的行为,因为存储阵列外部通常会修改其他人使用的存储对象,而大多数现代系统缺少捕获这些对象的运行时检查错误。程序不应依赖于捕获的缓冲区溢出。

通常的规则有一个例外,即可移植程序不能数组外部的地址。在C中,只计算地址是有效的越过一个物体,例如。,&a【否】哪里N个元素,只要不取消引用结果指针。但事实并非如此对于刚好在对象(例如。,&a[-1];计算末尾后的两个也无效,例如。,&a[N+1].打开大多数平台&a[-1]<&a[0]&&a[N]<&a[N+1],但这不是一般来说是可靠的,通常很容易避免潜在的可移植性问题,例如,通过分配额外的未使用数组元素位于开头或结尾。

瓦尔格林德可以捕获许多超限。GCC用户也可以考虑使用-f消毒=选项抓住超支。请参阅程序检测选项在里面使用GNU编译器集合(GCC).

缓冲区溢出通常是由off-by-one错误引起的,但有更微妙的获取方式。

使用整数值以索引到数组或计算数组大小在典型的64位主机上导致问题,其中阵列索引可能2^{31}或更大。类型的索引值尺寸_t避免这样问题,但不能是负面的。类型的索引值ptrdiff(_t)签名,并且在实践中足够宽。

如果您将两个数字相加或相乘以计算数组大小,例如。,malloc(x*sizeof y+z),如果添加或乘法溢出。

的许多实现阿洛卡函数无声地行为不端如果给定的大小太大,则会生成缓冲区溢出。大小限制取决于实施,但至少为4000我们所知道的所有平台上的字节数。

标准功能asctime时间,asctime_,ctime公司,活动_ r、和得到容易发生缓冲区溢出,并且除非已知输入是在一定限度内。与时间相关的函数会溢出其缓冲区,如果给定的时间戳超出范围(例如,一年小于-999或大于9999)。与时间相关的缓冲区溢出不会发生GNU C库的最新版本,但可能与其他人实现。这个得到功能最差,因为它几乎当出现较大的输入行时,总是溢出其缓冲区而不是缓冲区。