如果数组是否溢出,则打印

Print if the array is overflowing or not

本文关键字:打印 溢出 数组 是否 如果      更新时间:2023-10-16

所以我有这个数组,它将存储两个数组相加的结果。这个数组的大小是10,并且要添加的数字的数组的大小也是10

我的问题是如果数组在加法后溢出,我想打印"Overflow",如果数组中的元素数在加法后不超过10,则打印"No change"

我正在尝试实现两个案例:

i。首先是将'result'数组的大小增加到11,然后给出条件

if (result[11]!=int(32))
    cout<<"Overflow"<<endl; 

ii。我尝试使用的另一个逻辑是:

int count = 0;
for (int i=0;i<11;++i){
    if (result[i]!= int(16))
       ++count;
}
cout<<count<<endl;
if (count >10)
    cout<<"Overflow"<<endl;

问题是,即使结果由数组中的10数字组成,它也会将count打印为11

我也在考虑使用动态数组,但我是C++的新手,所以不知道这是否是个好主意。我希望你能给我一些建议。

您可以做的一件事是在数组外创建一个缓冲区来捕获额外的写入:

int array[SIZE + 1];
array[SIZE] = MAGIC;
// use array [0... SIZE-1]
if (array[SIZE] != MAGIC) /* overflowed */

然而,虽然这种捕获超出了缓冲区的大小,但如果代码超过了缓冲区,则存在未定义的行为,并且不能保证在UB发生后,最后的if测试能够正常工作。写入的实际值也有一点机会等于MAGIC。。。但如果你正确选择金丝雀值,这种情况发生的可能性很小。

不过,对于溢出检测来说,这是一个非常好的开始,而且大多数动态分配器在调试编译中都会这样做。

一种更先进的技术是将数组放在内存的无效区域旁边,在这种情况下,CPU硬件(确切地说是内存保护单元)将在越界访问的确切位置生成陷阱(访问违规或SIGSEGV)。efence库使用了这种技术。

问题是,它将计数打印为"11",即使结果由数组中的10个数字组成。

这是因为您的循环运行了11次,同时递增计数11次,即从0到10。

for (int i = 0; i < 11; i++)

问题是,它将计数打印为"11",即使结果由数组中的10个数字组成。

如果我理解正确的话,您正在访问大小为10的数组的第10个索引,这是未定义的行为,因为它是越界访问。

如果您使用的是C++03,则可以避免使用原始数组,而选择std::vectorstd::vector会自动为您处理内存,如果您尝试提供越界索引,它的at()成员函数将抛出异常。请注意,operator[]不提供边界检查。

在C++11中,您可以使用std::array。与std::vector类似,它具有提供边界检查的at()和不提供边界检查。非成员函数std::get提供编译时边界检查。这里有一个例子:

std::array<int, 5> arr { 1, 2, 3, 4, 5 };
std::get<6>(arr);
// error: static assertion failed: index is out of bounds
arr.at(6);
// terminate called after throwing an instance of 'std::out_of_range'
//   what():  array::at: __n (which is 6) >= _Nm (which is 5)

如果你一直使用原始数组,你的编译器可能会提供诊断或工具来帮助捕捉越界错误,例如LLVM的未定义行为清理程序(已移植到GCC)和Valgrind(报告内存错误)。以下是Clang发出越界警告的示例:

int arr[5] = { 1, 2, 3, 4, 5 };
arr[6];
// warning: array index 6 is past the end of the array (which contains 5 elements) [-Warray-bounds]

如果你用-fsanitize=address,undefined:运行它,你会得到消息

runtime error: index 6 out of bounds for type 'int [5]'

GCC捕获循环中未定义的行为:

for (int i = 0; i < 6; ++i)
    std::cout << arr[i];
// warning: iteration 5u invokes undefined behavior [-Waggressive-loop-optimizations]

这是使用-Wall -Wextra -pedantic的一个很好的论据,CCD_23适用于这两个编译器,尽管需要注意的是,您得到的确切诊断各不相同,所以请始终使用多个工具测试代码。

"我的问题是,如果数组在添加后溢出,我想打印"Overflow",如果数组中的元素数量在添加后不超过10,我要打印"No change"。"

您必须在访问之前进行越界索引检查,或者事先使用越界检查程序代码注入。