如果数组是否溢出,则打印
Print if the array is overflowing or not
所以我有这个数组,它将存储两个数组相加的结果。这个数组的大小是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::vector
。std::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"。"
您必须在访问之前进行越界索引检查,或者事先使用越界检查程序代码注入。
- 如何循环打印顶点结构
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 如何在c++中打印目录
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 在线编译器中的分段C++没有打印消息
- 'short int'持有的值溢出,但"自动"不会溢出?
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 大于65535的C++数组[size]引发不一致的溢出
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 如何将结构插入到集合中并打印集合的成员
- 在循环C++中指定字符串之后,不会打印该字符串
- 以螺旋方式打印矩阵的程序.(工作不好)
- 从控制台中删除最后打印的元素
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何仅使用对象名称打印特定于对象的成员
- 回溯C++不打印函数,因此文件
- 在一定长度后从数组中打印时缺少整数
- 奇怪的消息 (_Base_bitset::_M_do_to_ulong) 从溢出异常处理程序中打印出来
- 如果数组是否溢出,则打印