2014-11-01 4 views
0

Итак, у меня есть этот массив, который сохранит результат добавления двух массивов. Размер этого массива 10 и размер массивов чисел, которые будут добавлены также 10Печать, если массив переполнен или нет

Мой вопрос Я хочу напечатать "Overflow" если массив перетекает после добавления и печати "No change" если количество элементов в массиве, после добавления, не превышает 10.

Я пытаюсь реализовать 2 случая:

я. Во-первых, чтобы увеличить размер массива «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

Итак, вы в основном пытаетесь добавить проверку границ в примитивный массив? –

+0

Да, это был бы один из способов сказать это. –

+1

Поскольку вы используете C++, предпочитаете использовать 'std :: array' или' std :: vector'. Функция 'at()' member предоставляет проверку границ времени выполнения, в то время как 'std :: get' обеспечивает проверку границ сеансов. В противном случае рассмотрим использование инструмента статического анализа или clang и gcc '-fsanitize = undefined'. GCC также может выходить за пределы доступа с помощью предупреждения. –

ответ

1

Проблема заключается в том, что она печатает счет как «11», даже если результат состоит из 10 чисел в массиве.

Это потому, что цикл выполняется 11 раз, а также увеличивающееся количество 11 раз т.е. от 0 до 10.

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

Приращение счета не является безусловным. –

-1

«Мой вопрос я хочу напечатать» Перелив «если массив переполняется после добавления и печатает« Без изменений », если количество элементов в массиве после добавления не превышает 10."

Вы должны сделать из индекса границы проверок предыдущего доступа, или использовать отказ от инъекций коды Bounds Checker заранее.

+0

Вы также можете сделать хранилище больше, чем необходимо для массива, заранее занести канарейку в неиспользуемое пространство и впоследствии проверить, что он не был поврежден. Или используйте MPU, как это делает efence. Множество способов обнаружения доступа за пределы доступа. –

2

Одна вещь, которую вы можете сделать, это создать область буфера за пределами массива, чтобы поймать дополнительные Пишет:

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

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

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

Однако, в то время как это ловит перерасход до размера области буфера, если код идет прошлое, , у вас есть неопределенное поведение, и ваш тест if в конце не гарантированно работает должным образом после того, как произойдет UB. Также есть небольшая вероятность того, что фактическое значение будет записано равным MAGIC ... но шансы на это довольно малы, если вы правильно выберете канарейку.

Это довольно хороший старт для обнаружения переполнения, и большинство динамических распределителей делают что-то подобное в отладочных компиляторах.

Более совершенный метод заключается в том, чтобы разместить массив рядом с недопустимой областью памяти, и в этом случае аппаратное обеспечение ЦП (точнее, блок защиты памяти) создаст ловушку (нарушение доступа или SIGSEGV) на точное местоположение доступа за пределами границ. Библиотека efence использует эту технику.

+0

можно было бы немного его разработать? –

+0

@nothing: В какой части у вас были вопросы? –

+0

Я уже увеличил размер массива результатов от «10» до «11», поэтому почему нужно использовать буфер? –

0

Проблема заключается в том, что она печатает счет как «11», даже если результат состоит из 10 чисел в массиве.

Если я правильно понял это, вы получаете доступ к 10-му индексу массива размера 10, который является неопределенным поведением, потому что он находится за пределами доступа.

Если вы используете C++ 03, вы можете избежать использования необработанных массивов и предпочесть std::vector. std::vector автоматически обрабатывает память для вас, а функция-член at() будет генерировать исключение, если вы попытаетесь предоставить индекс за пределами границ. Будьте уверены, что operator[] не обеспечивает проверку границ.

В C++ 11 вы можете использовать std::array. Подобно std::vector, он имеет at(), который обеспечивает проверку границ и operator[], что нет. Функция non-member 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 в дезинфицирующее (который был портирован на НКУ) и 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]' 

НКУ ловли неопределенное поведение в цикле:

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

Это хороший аргумент для использования -Wall -Wextra -pedantic, которые работают для обоих компиляторов, хотя имейте в виду, что точная диагностика вы получаете отличаться, поэтому всегда проверить свой код с кратному инструменты.