所以我有这个数组会存储两个数组相加的结果。此数组的大小为10
,要添加的数字的数组大小也为10
我的问题是如果数组在添加后溢出,我想打印"Overflow"
并打印"No change"
如果数组中的元素数量在添加后不超过{ {1}}。
我正在尝试实施2个案例:
我。首先是将“ 10
”数组的大小增加到11,然后给出条件
result
II。我试图使用的另一个逻辑是:
if (result[11]!=int(32))
cout<<"Overflow"<<endl;
问题是,即使结果中包含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;
个数字,它也会将 count
打印为11
。
我也在考虑使用动态数组,但我是C ++的新手,所以不知道这是不是一个好主意。我会很感激一些建议。
答案 0 :(得分:2)
您可以做的一件事是在数组外部创建一个缓冲区来捕获额外的写入:
int array[SIZE + 1];
array[SIZE] = MAGIC;
// use array [0... SIZE-1]
if (array[SIZE] != MAGIC) /* overflowed */
但是,虽然这会超出缓冲区域的大小,但如果代码超过了该范围,则会出现未定义的行为,并且在UB发生后,最终的if
测试无法保证正常工作。写入的实际值也有可能等于MAGIC
...但如果你正确选择金丝雀值,那么发生这种情况的可能性非常小。
但是,对于溢出检测来说,这是一个非常好的开端,并且大多数动态分配器在调试编译中执行类似的操作。
更高级的技术是将数组放在无效的内存区域旁边,在这种情况下,CPU硬件(确切地说是内存保护单元)将生成一个陷阱(访问冲突或SIGSEGV)。越界访问的位置。 efence
库使用此技术。
答案 1 :(得分:1)
问题是,它将计数打印为&#39; 11&#39;即使结果 由数组中的10个数字组成。
这是因为你的循环运行了11次,并且计数增加了11次,即从0增加到10次。
for (int i = 0; i < 11; i++)
答案 2 :(得分:0)
问题是,它将计数打印为&#39; 11&#39;即使结果 由数组中的10个数字组成。
如果我理解正确,那么您正在访问大小为10的数组的第10个索引,这是一个未定义的行为,因为它超出了界限。
如果你正在使用C ++ 03,你可以避免使用原始数组,而更喜欢std::vector
。 std::vector
会自动为您处理内存,如果您尝试提供越界索引,则其at()
成员函数将抛出异常。请注意operator[]
不提供边界检查。
在C ++ 11中,您可以使用std::array
。与std::vector
类似,它提供at()
提供边界检查,而operator[]
则提供边界检查。非成员函数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
的一个很好的论据,它适用于两个编译器,但是请注意,您获得的确切诊断会有所不同,因此请始终使用多个工具测试您的代码。
答案 3 :(得分:-1)
“我的问题是,如果阵列在添加后溢出并打印”无变化“,我想打印”溢出“,如果数组中的元素数量在添加后不超过10。”
您必须在访问之前进行越界索引检查,或事先使用越界检查器代码注入。