Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/21: Рейтинг темы: голосов - 21, средняя оценка - 4.52
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6

Реализация защиты выхода за границы массива

08.12.2014, 21:21. Показов 4177. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени! Прошу помочь разобраться с вопросом возникшим, при изучении C++. Я только начинаю изучать язык и ни как не могу понять вот такой момент. Ниже приведен код перегрузки оператора []. Ни как не могу понять почему если данный оператор вызывается для изменения элемента массива и переменной 'dummy' присваивается значение нулевого байта не второй строкой как в коде а в одной строке вот так: static char dummy = '\0'. Тогда в переменную записывается значение и при выводе это видно. А если реализовано как в примере, она всегда остается нулевой. Буду очень признателен за помощь.

C++
1
2
3
4
5
6
7
char & String::operator[] (int i)
{
    if (0<=i && i<n) return s[i];
    cerr << "Index out of range" << endl;
    static char dummy;
    dummy = '\0';
        return dummy;
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.12.2014, 21:21
Ответы с готовыми решениями:

Создайте класс динамического массива, в котором реализована проверка выхода за границы массива
Народ подскажите такую вещь я написал программку для вставки элементов в массив при этом осуществляется проверка границ массива ! ...

Создайте класс динамического массива, в котором реализована проверка выхода за границы массива
Создайте класс динамического массива, в котором реализована проверка выхода за границы массива. Перегрузите операторы: , =, +, -,++ ...

Создайте класс динамического массива, в котором реализована проверка выхода за границы массива
Создайте класс динамического массива, в котором реализована проверка выхода за границы массива. Перегрузите операторы: , =, +, -,++...

11
 Аватар для Pancir
59 / 46 / 11
Регистрация: 16.09.2014
Сообщений: 124
08.12.2014, 21:40
static char dummy; - это объявление и создание переменной, делается один раз.
static char dummy = '\0'; - это объявление и создание переменной и ее инициализация, делается один раз. (на заметку, делать инициализацию - это правильно)
dummy = '\0'; - это уже присваивание значения переменной, делается каждый раз при вызове вашего оператора.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 21:49  [ТС]
Pancir,
Это я все понимаю, спасибо.
Пример клиентского кода где, индекс 100 это выход за пределы массива, если инициализация dymmy происходит в отдельной строке:
C++
1
2
3
4
5
a[0] = 'h';
    a[100] = '@';
    cout << "a[100] = " << a[100] << endl;  // выводит такой результат a[100] =
    cout << "Sting a: \""; a.Print();
    cout << "\", Len=" << a.Len() << endl << endl;

Пример клиентского кода где, индекс 100 это выход за пределы массива, если инициализация dymmy происходит одновременно с объявлением т. е вот так static char dummy = '\0' :

C++
1
2
3
4
5
a[0] = 'h';
    a[100] = '@';
    cout << "a[100] = " << a[100] << endl;  // выводит такой результат a[100] = @
    cout << "Sting a: \""; a.Print();
    cout << "\", Len=" << a.Len() << endl << endl;
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.12.2014, 21:56
IvanVladim, в обоих случаях при выходе за диапазон наружу возвращается ссылка на dummy

C++
1
a[100] = '@';
Здесь возвращается ссылка на dummy, а затем dummy присваивается значение '@'
Но в первом случае оно каждый раз перезаписывается в ноль.

А во втором случае не перезаписывается.
0
 Аватар для Pancir
59 / 46 / 11
Регистрация: 16.09.2014
Сообщений: 124
08.12.2014, 22:02
IvanVladim
Ваш код так и должен работать как вы описываете.
Если вам не понятно почему это так работает, читайте внимательнее мое предыдущее сообщения, правда уточнение для 3-й строчки, не каждый вызов оператора, а каждый вызов с "не пройденным" if.

Если кратко, то ваш код из первого сообщения работает просто: если выход за границы массива, то ставим dummy - '\0' и возвращаем ссылку на него.

если сделать одну строчку static char dummy = '\0'; то код будет работать так: если вышли за пределы, ничего не делать, просто вернуть ссылку на переменную dummy, которая из-за того, что static, хранит предыдущее записанное в нее значение.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 22:43  [ТС]
hoggy,

Вот этого я и не могу понять.
Вот как я понимаю, если не прав поправьте:

когда я пишу a[100]='@' я выхожу за границы массива, работает следующий код компилятор видит квадратные скобки и вызывает функцию, которая объявлена в хэдер файле следующим образом:

C++
1
char & String::operator[] (int i)
соответсвенно работает функция operator[] которая принимает int и возвращает ссылку на char

так как мы вышли за границу массива работают следующие строчки:

C++
1
2
3
4
cerr << "Index out of range" << endl;
    static char dummy;
    dummy = '\0';
        return dummy;
создается статическая переменная с присвоенным значением '\0' , и ссылка на нее передается вызывающему коду, т.е. a[100]='@' и после того как он получил ссылку он изменяет значение на dummy на '@'.
Или я не прав?

и вызывающий код такого вида:

C++
1
2
    a[100] = '@';
    cout << "a[100] = " << a[100] << endl;
должен напечатать '@' а не '\0'

Что я не так понимаю?

Добавлено через 2 минуты
И почему

C++
1
static char dummy = '\0';

Выводит '@'

а

C++
1
2
        static char dummy;
    dummy = '\0';

выводит '\0'

???
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.12.2014, 23:05
Цитата Сообщение от IvanVladim Посмотреть сообщение
Или я не прав?
Давайте по шагам:

C++
1
2
3
4
a[100] = '@';    //dummi приняло значение 0, а следом  значение @
 
cout << "a[100] = " << a[100] //dummi приняло значение 0
 << endl;
вы в cout дергаете a[100]
при этом оно у вас обнуляется, но новое значение никто не выставляет. Вот и получаете ноль.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 23:12  [ТС]
hoggy, Спасибо, теперь дошло, при выводе снова вызывается функция и уже на чтение и ей снова присваивается ноль.

Правильно ли я понимаю, что модификатор static предопределяет создание переменной один раз при запуске программы или при первичном вызове данной функции и при последующих уже не работатет, и если присваивание ноля совместить то при следующем вызове функции эта строка не отрабатывает?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.12.2014, 23:19
Цитата Сообщение от IvanVladim Посмотреть сообщение
Правильно ли я понимаю, что модификатор static предопределяет создание переменной один раз при запуске программы или при первичном вызове данной функции и при последующих уже не работатет, и если присваивание ноля совместить то при следующем вызове функции эта строка не отрабатывает?
Рассмотрим две конструкции:

C++
1
2
3
4
5
int a=10; //<--- создается переменная,которая уже содержит число 10
 
int b; //создается переменная, которой не указали значение при старте. Поэтому оно содержит мусор
 
b=10; //теперь уже существующей переменной установили значение 10
ключевое слово static означает что переменная должна быть создана в статической области памяти.
время жизни до конца программы.
То есть, статическая переменная может быть создана только один раз, и её время жизни - до конца программы.

Если при этом указать с каким значение нужно создать статическую переменную, то она будет создана только один раз с указанным значением.

Теперь рассмотрим статическую локальную переменную:

C++
1
2
3
4
5
int& foo()
{
    static int v = 10; 
    return v;
}
локальные статические переменные так же, как и обычные статические переменные создаются только один раз, и время их жизни так же до конца программы.

Но в отличие от обычных статических переменных, локальные инициализируются в момент первого запуска функции. Инициализация может происходить только при создании переменной. Таким образом инициализация локальной статической переменной происходит только один раз при первом вызове функции.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 23:41  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
Но в отличие от обычных статических переменных, локальные инициализируются в момент первого запуска функции. Инициализация может происходить только при создании переменной. Таким образом инициализация локальной статической переменной происходит только один раз при первом вызове функции.
И после такой инициализации:
C++
1
static int v = 10;
в последующих инструкциях в рамках функции я ее могу изменять?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.12.2014, 23:43
Цитата Сообщение от IvanVladim Посмотреть сообщение
в последующих инструкциях в рамках функции я ее могу изменять?
Да, как и обычную переменную.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 23:46  [ТС]
hoggy, Премного благодарен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.12.2014, 23:46
Помогаю со студенческими работами здесь

Класс динамического массива с проверкой выхода за границы массива
Задание такое: Создайте класс динамического массива, в котором реализована проверка выхода за границы массива. Перегрузите операторы: ,...

Помогите исправить ошибку выхода за границы массива
Проблема состоит в следующем - необходимо добавить строки в конец рваного массива. button3-&gt;Создаю массив через поля справа -&gt;...

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

Ошибка выхода за границы массива, когда её быть не должно
Вот функция: public IntPtr getmas() { char chars =...

Ошибка выхода за границы памяти
При вызове функции сортировки слиянием (код прилагаю) происходит ошибка: Вызвано исключение: нарушение доступа для записи. tmp было...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru