如果阵列溢出或打印,则打印

时间:2014-11-01 15:45:38

标签: c++ arrays

所以我有这个数组会存储两个数组相加的结果。此数组的大小为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 ++的新手,所以不知道这是不是一个好主意。我会很感激一些建议。

4 个答案:

答案 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::vectorstd::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。”

  

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