0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
1

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

08.12.2014, 21:21. Показов 3615. Ответов 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.12.2014, 21:21
Ответы с готовыми решениями:

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

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

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

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

11
58 / 45 / 11
Регистрация: 16.09.2014
Сообщений: 124
08.12.2014, 21:40 2
static char dummy; - это объявление и создание переменной, делается один раз.
static char dummy = '\0'; - это объявление и создание переменной и ее инициализация, делается один раз. (на заметку, делать инициализацию - это правильно)
dummy = '\0'; - это уже присваивание значения переменной, делается каждый раз при вызове вашего оператора.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 21:49  [ТС] 3
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
Эксперт С++
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
08.12.2014, 21:56 4
IvanVladim, в обоих случаях при выходе за диапазон наружу возвращается ссылка на dummy

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

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

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

если сделать одну строчку static char dummy = '\0'; то код будет работать так: если вышли за пределы, ничего не делать, просто вернуть ссылку на переменную dummy, которая из-за того, что static, хранит предыдущее записанное в нее значение.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 22:43  [ТС] 6
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
Эксперт С++
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
08.12.2014, 23:05 7
Цитата Сообщение от 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  [ТС] 8
hoggy, Спасибо, теперь дошло, при выводе снова вызывается функция и уже на чтение и ей снова присваивается ноль.

Правильно ли я понимаю, что модификатор static предопределяет создание переменной один раз при запуске программы или при первичном вызове данной функции и при последующих уже не работатет, и если присваивание ноля совместить то при следующем вызове функции эта строка не отрабатывает?
0
Эксперт С++
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
08.12.2014, 23:19 9
Цитата Сообщение от 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  [ТС] 10
Цитата Сообщение от hoggy Посмотреть сообщение
Но в отличие от обычных статических переменных, локальные инициализируются в момент первого запуска функции. Инициализация может происходить только при создании переменной. Таким образом инициализация локальной статической переменной происходит только один раз при первом вызове функции.
И после такой инициализации:
C++
1
static int v = 10;
в последующих инструкциях в рамках функции я ее могу изменять?
0
Эксперт С++
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
08.12.2014, 23:43 11
Цитата Сообщение от IvanVladim Посмотреть сообщение
в последующих инструкциях в рамках функции я ее могу изменять?
Да, как и обычную переменную.
0
0 / 0 / 0
Регистрация: 08.12.2014
Сообщений: 6
08.12.2014, 23:46  [ТС] 12
hoggy, Премного благодарен.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.12.2014, 23:46
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru