Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
1

Почему массив не переполняется?

02.02.2011, 06:52. Показов 1785. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вот в одной книге есть задание создать вектор и скопировать элементы в массив. Почему массив не переполняется в следующем коде, какая-то загадка для меня. Вроде бы после введения 2-3 элементов он не должен больше принимать, а он принимает, и только после введения 6 элементов программа завершается с ошибкой, а 5 спокойно запоминает, ладно бы вектор, а тут массив, вроде бы с определенным размером:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
int i = 0;
     int ar1[2];
     vector <int> ivec (0);
           while (cin >> i) 
      ivec.push_back(i);
                  for (vector<int>::size_type j = 0; j != ivec.size(); ++j) {
           ar1[j] = ivec[j];
           cout << ivec[j] << ar1[j] << endl;
            }
     getch();
     return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2011, 06:52
Ответы с готовыми решениями:

не переполняется динамический массив
Заметил странную штуку: при заполнении динамического массива в цикле, когда счётчик становится...

Переполняется стек
Вот код: #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;algorithm&gt; using namespace std; ...

Почему возможно задать массив с размером -1 (почему такое вообще компилируется)?
Всем привет. Долгое время не писал на плюсах, решил пройтись по основам, вспомнить. По...

Почему переполняется стек
Написал программу, но не пойму почему переполняется стек. Суть программы - возведение в степень ч/з...

22
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
02.02.2011, 06:59 2
AdPotam, Все очень просто, С не контролирует размер массивов и ты можешь спокойно пихать данные за его пределы, и затереть соседние данные. А ошибка возникнет только тогда, когда программа начнет эти соседние данные использовать )
1
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
02.02.2011, 08:04  [ТС] 3
Но почему тогда только при введении именно 6-и символов программа вылетает? Вот что заставило меня подумать, что в этом есть какая-то закономерность. А не, допустим, 4 или 9-и? Я изучаю С++, возможно, этот язык контролирует размер массивов? Вот что об этом пишется в книге, по которой учусь:
Переменная типа массива имеет три важных ограничения: она имеет фиксированный размер, этот размер должен быть известен на момент компиляции, и наконец, массив существует только до конца блока, в котором он был определен.
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
02.02.2011, 08:13 4
Тут еще зависит от того в релизе ты проверял или под дебагером?
Эта величина не совсем случайна, есть определенные закономерности в выделении памяти программы.
0
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
02.02.2011, 08:20  [ТС] 5
Компилил, как тут мне посоветовали, GCC, а писал в блокноте Кажется, это релиз, а функций дебагера у него нет, только на ошибки указывает. Словом, насколько я понял, тут не всё просто, и лучше не заморачиваться, а чтобы исключить неожиданности, лучше за пределы массива не выходить. Так?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
02.02.2011, 08:31 6
AdPotam, Это само собой, чем кончится выход за границы никто не знает, поразному бывает, программа может работать но глючить в разных местах из за такого.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
02.02.2011, 09:38 7
Цитата Сообщение от AdPotam Посмотреть сообщение
vector <int> ivec (0);
Это не обычный массив С с парой-тройкой функций. Независимо от того, какой размер был задан в конструкторе, при необходимости он может быть увеличен. Короче, так Вы переполнения "массива" вряд ли добьётесь. Разве, что всю доступную память израсходуете.
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
02.02.2011, 09:51 8
easybudda, эмм... Полагаю, вопрос был про переполнение массива ar1, который является обычным Си-массивом из двух элементов.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
02.02.2011, 10:17 9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Полагаю, вопрос был про переполнение массива ar1
Точно, не разглядел. Тогда всё проще. Элементы будут помещаться в массив, пока стек не кончится.
Если в стеке после массива есть ещё что-то - оно затрётся.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.02.2011, 10:21 10
easybudda, ты хоть код читал? Он выходит за пределы совсем другого массива.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
02.02.2011, 11:07 11
Цитата Сообщение от taras atavin Посмотреть сообщение
ты хоть код читал?
мало того - скомпилировал и выполнил. А ты?
Код
C:\cpp\shitcode>out2
1
2
3
4
5
^Z
11
22
33
44
55
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.02.2011, 11:10 12
Компиляция здесь причём? Компил его совсем не так читает. Или ты его вручную компилил и в голове выполнял? Надо было не компилить копипасту, а внимательно читать, тогда бы ты знал, в какую сторону выполняется присваивание и что должно переполняться.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
02.02.2011, 13:09 13
Цитата Сообщение от taras atavin Посмотреть сообщение
Или ты его вручную компилил и в голове выполнял?
Юмор?
Цитата Сообщение от taras atavin Посмотреть сообщение
внимательно читать, тогда бы ты знал, в какую сторону выполняется присваивание и что должно переполняться.
Про то, "в какую сторону выполняется присваивание", наверное между строк читать нужно было?
Имя массива int ar1[2] суть - адрес куска памяти, находящегося в стеке, достаточного, или большего, чем требуется для размещения двух значений типа int. Пока индекс за границу этого куска не выходит, всё как буд-то работает.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.02.2011, 13:11 14
Цитата Сообщение от easybudda Посмотреть сообщение
Имя массива int ar1[2] суть - адрес куска памяти, находящегося в стеке, достаточного, или большего, чем требуется для размещения двух значений типа int.
Ну я то об этом знаю. И ещё про отсутствие контроля этого самого индекса. А вот ты операнды явно попутал.
0
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
02.02.2011, 13:37  [ТС] 15
Понятно, спасибо всем ответившим! Есть легкое удивление, почему это разработчики языка С не додумались жестко ограничить размеры массива, а не провоцировать ситуации, когда возможны всякие ошибки. Ну да ладно, и на том, как говорится, спасибо.

Добавлено через 4 минуты
easybudda, Про то, "в какую сторону выполняется присваивание", наверное между строк читать нужно было?
Мне, даже начинающему, как будто бы понятно, куда выполняется присваивание - массиву:
C++
1
ar1[j] = ivec[j]
Или тут есть нюансы?
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.02.2011, 13:41 16
Нюанс в том, что они оба массивы. Только один из (вектор) саморасширяемый, а другой обычный.

Добавлено через 2 минуты
Цитата Сообщение от AdPotam Посмотреть сообщение
а не провоцировать ситуации, когда возможны всякие ошибки.
Ошибки провоцируются мифом о защите от ошибок. Вот в делфях защита якобы есть, так я несколько раз получал такие глюки при обработке элементов за пределами массива! И ни разу защита не сработала. А на сях сам думаешь о границах массива и о соседних данных и ошибки исключены.
1
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
02.02.2011, 13:46  [ТС] 17
taras atavin: Массивы с обеих сторон.
В книге, по которой я учусь, массывы существенно различаются от векторов, а ivec, насколько я понимаю, вектор.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.02.2011, 14:02 18
Вектор. Но понятие массива многозначно.
Массивом называется составное данное, состоящее и из элементов, каждый из которых адресуется уникальным в пределах массива индексом, или набором индексов
. Отсюда вектор - вид массива.
Статическим массивом называется массив у которого число элементов - константа, но сами элементы - переменные.
К вектору это не относится. Но есть и другие массивы:
ограниченным массивом называется массив, при обращении к несуществующему элементу которого срабатывает защита доступа.
,
динамическим массивом называется массив, у которого могут меняться не только сами элементы, но и их количество.
,
константным массивом называется массив, у которого не только количество элементов - константа, но и сами элементы тоже константы.
. Отсюда вектор - динамический, но не ограниченный массив. Но лучше чтоб не провоцировать путаницу вектор массивом не называть.

Добавлено через 6 минут
Мало того, вектора тоже бывают разные.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class TVector
{
 public:
  double x,y,z;
  TVector ();
  TVector (TVector &x);
  TVector operator = (TVector &x);
  TVector operator + (TVector &x);
  TVector operator - (TVector &x);
  TVector operator * (TVector &x);
  TVector operator * (double x);
  TVector operator / (double x);
  void operator += (TVector &x);
  void operator -= (TVector &x);
  void operator *= (TVector &x);
  void operator *= (double x);
  void operator /= (double x);
  friend TVector operator * (double x, TVector &y);
  friend double abs(TVector &x);
};
тоже вектор.
1
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
02.02.2011, 16:07 19
Цитата Сообщение от AdPotam Посмотреть сообщение
Есть легкое удивление, почему это разработчики языка С не додумались жестко ограничить размеры массива, а не провоцировать ситуации, когда возможны всякие ошибки.
Ну ответ очевиден - это сделано для скорости. В контейнерах std::vector, std::deque и std::string тоже при указании индекса в квадратных скобках его правильность не проверяется, и если он вышел за пределы, то поведение программы неопределенное. Для получения элемента этих контейнеров по индексу с его проверкой используется функция-член at (которая, естественно, работает медленнее). В случае выхода индекса за пределы она генерирует исключение out_of_range.
0
2 / 2 / 0
Регистрация: 29.11.2010
Сообщений: 73
02.02.2011, 16:20  [ТС] 20
Всё понял, век живи = век учись
0
02.02.2011, 16:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.02.2011, 16:20
Помогаю со студенческими работами здесь

Почему не загружается картинка, но при этом переполняется память?
Всем доброго времени суток!Я хотел бы узнать почему не загружается картинка и при этом...

Стек переполняется и переполняется...
Короче говоря, в ходе написания программы наткнулся на то, что все время вылетает ошибка о том, что...

Память переполняется
Вот код. Не могу понять. Все равно память переполняется и прога не работает. protected void...

Переполняется папка TEMP
папка TEMP, как я примерно определил, при запуске IE или Opera начинает очень быстро забиваться...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru