2014-11-01 28 views
0

所以我有这个数组可以存储添加两个数组的结果。该数组的大小是10和要添加的数字的数组的大小也10打印数组是否溢出

我的问题是我想打印"Overflow"如果相加后的数组溢出,如果打印"No change"元素个数在添加之后,排列不会超过10

我试图实施2种情况:

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; 

问题是,它是打印count作为11即使结果由数组中10数字。

我也想使用动态数组,但我是C++的新手,所以不知道这是否是一个好主意。我希望提供一些建议。

+1

那么,你基本上是试图增加边界检查,基本数组? – 2014-11-01 15:48:15

+0

是的,这将是一种说法。 – 2014-11-01 15:51:00

+1

由于您使用的是C++,因此宁愿使用'std :: array'或'std :: vector'。 'at()'成员函数提供了运行时边界检查,而'std :: get'提供了编译时间边界检查。否则,请考虑使用静态分析工具或clang和gcc的'-fsanitize = undefined'。海湾合作委员会也可能通过警告超出界限。 – 2014-11-01 15:52:16

回答

1

问题是,它是印刷的计数为“11”即使结果 由阵列中的10个号码。

这是因为你的循环运行11次,以及增加计数即11次从0到10

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

计数的增量不是无条件的。 – 2014-11-01 15:53:52

-1

“我的问题是要打印的”溢出“如果添加后数组溢出并且打印”无变化“,如果添加之后数组中元素的数量不超过10个。”

你必须做出界索引检查之前访问,或者使用越界检查代码注入预先。

+0

您还可以使存储大于所需的阵列,存储在未使用的空间金丝雀事前,事后检查它没有被破坏。或者使用MPU,就像efence一样。许多方法来检测出界限访问。 – 2014-11-01 15:53:34

2

一两件事你可以做的是建立一个缓冲区域阵列外搭上额外写道:

int array[SIZE + 1]; 
array[SIZE] = MAGIC; 

// use array [0... SIZE-1] 

if (array[SIZE] != MAGIC) /* overflowed */ 

然而,尽管这种捕捉溢出到缓冲器区域的大小,如果代码变过去那种,您有未定义的行为,并且在UB发生后,您的if测试不能保证能够正常工作。实际价值写入的机会也很小,等于MAGIC ......但如果您正确选择金丝雀值,发生这种情况的几率相当小。

尽管这是一个非常好的超限检测开始,而且大多数动态分配器在调试编译时都是这样做的。

更高级的技术是将阵列放置在内存的无效区域的旁边,在这种情况下,CPU硬件(准确地说是内存保护单元)将会在内存中生成陷阱(访问冲突或SIGSEGV)确定出界的准确位置。 efence库使用这种技术。

+0

是否可以详细阐述一下? – 2014-11-01 16:00:50

+0

@ nothing:您对哪部分有疑问? – 2014-11-01 16:02:31

+0

我已经将结果数组的大小从'10'增加到了'11',为什么需要使用缓冲区? – 2014-11-01 16:06:18

0

问题是,即使结果 包含数组中的10个数字,它也会将计数值打印为'11'。

如果我正确理解这一点,您将访问大小为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的(所报道的内存错误)下面是锵给人的出界警告的例子:

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,这两种编译器的工作奠定了良好的说法,但被警告,你得到确切的诊断各不相同,所以总是测试多代码工具。