Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.76/263: Рейтинг темы: голосов - 263, средняя оценка - 4.76
 Аватар для pcmax
443 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,274

В чем разница между динамическим массивом и статическим?

07.01.2019, 11:59. Показов 58072. Ответов 220
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
ребята, я не понимаю различия. вроде читал литературу.

ну вот говорят, что динамический массив, это массив выделение памяти под который будет происходит в процессе выполнения программы.

и тут я залез в онлайн компилятор (с++ 14) и сделал так
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main(){
 
int n;
std::cin >> n;
int array[n]; // ну я создал посути динамический массив.
 
int *arr;
arr=new int[n]; // здесь тоже. 
return 0;
}
 
значит они оба динамические?
объясните пожалуйста в чем действительно разница между статическим и динамическим массивом, чтобы я мог точно понимать что есть что
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.01.2019, 11:59
Ответы с готовыми решениями:

Разница между статическим и динамическим полиморфизмом
Добрый день Подскажите пожалуйста какая разница между статическим и динамическим полиморфизмом и пожалуйста на примере и virtual...

В чем разница между вектором и массивом
Я учу язык С/С++ и хотел у вас спросить в чем разница между вектором и массивом ? кроме тогдо что вектор создается vector<int> m; а...

В чем разница между обычным массивом и контейнером
В чем разница между обычным массивом и контейнером?

220
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
09.01.2019, 22:45
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
А Вы знаете хоть одну реализацию компилятора, которая бы на 100% соответствовала стандарту, не содержала багов и других сюрпризов?
Я не анализировал компиляторы подобным образом...

Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Однако, зачастую, разработчик хорошо знает платформу для которой пишет, и знает как будет работать тот или иной фрагмент кода на целевых платформах, поэтому может использовать средства не соответствующие стандарту. И это вполне нормально.
Да, но для С++ это действительно когда речь идет о Unspecified behavior/Implementation defined, но никак не про Undefined behavior.
Опять же. Речь о С++ а не про платформы
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
09.01.2019, 22:47
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну вот здесь есть довольно показательный пример, как мне кажется.
А еще можно привести std::string::operator[]
C++
1
2
3
4
5
6
7
8
std::string s1("abc");
const std::string s2("abc");
//до C++11
char x = s1[s1.size()];//UB
char x = s2[s2.size()];//Ok
//начиная с C++11
char x = s1[s1.size()];//Ok
char x = s2[s2.size()];//Ok
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
09.01.2019, 22:51
Цитата Сообщение от Undisputed Посмотреть сообщение
Да, но для С++ это действительно когда речь идет о Unspecified behavior/Implementation defined, но никак не про Undefined behavior.
Кто Вам такое сказал?
Для undefined behavior в стандарте также сказано:
Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
2
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
09.01.2019, 22:59
HelicopterK52,
Если что то документировано то это другое дело.
Я же говорю про то что не документировано и с точки зрения с++ а не конкретных платформ
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
09.01.2019, 23:07
Цитата Сообщение от Undisputed Посмотреть сообщение
Если что то документировано то это другое дело.
Так оно документировано, просто не стандартом c++. Стандарт принципиально не способен задокументировать всё.
Банальный пример - запись по не выровненному адресу. На каких-то платформах это будет нормально работать, а на каких-то вывалится здоровенная аппаратная ошибка.
Как стандарт c++ должен подобное документировать? Только как undefined (или unspecified) behavior.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
09.01.2019, 23:09
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Так оно документировано, просто не стандартом.
Ну вот кстати что модель многопоточности, что каст функций в void * вполне документированы стандартом POSIX. При этом стандарту C++98 это никак не мешало вообще не описывать эти вещи у себя.
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
09.01.2019, 23:16
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну вот кстати что модель многопоточности, что каст функций в void * вполне документированы стандартом POSIX.
До C++11 многопоточности в с++ вообще не существовало, а многопоточные программы на C++ были. Как так?
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
09.01.2019, 23:20
HelicopterK52,
Согласен, этим никто не спорит...
Платформозависимые фичи часто используется
Я против документированного поведения ничего не имею
Конкретно в данном случае речь о том что, "я думаю что будет работать так", а гарантий нет.
Тут даже конкретная платформа не обсуждалась
Тоже понимаю что работать скорее всего будет и даже писал об этом
но гарантий нет
Речь об этом...
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
09.01.2019, 23:24
Цитата Сообщение от Undisputed Посмотреть сообщение
Даже несмотря на то, что вы делаете это от имени вспомогательного указателя, это не отменяет тот факт что фактический объект лежащий в памяти по адресу int * pa =reinterpret_cast<int*>(a); это тот самый двумерный массив 3х3, первый оператор идексации которого может быть в диапазоне 0-2.
Очень близко, но на самом деле UB наступит раньше выхода за диапазон 0-2.

Теперь подробнее.
Есть объект a типа int[3][3]. Что является значением указателя pa, инициализированного как int * pa =reinterpret_cast<int*>(a);?
Ну, во-первых, a попадает под array-to-pointer conversion, т.к. reinterpret_cast между указателями требует prvalue аргумент, а
Цитата Сообщение от https://timsong-cpp.github.io/cppwp/n4659/expr#9
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.
reinterpret_cast<int*>(a) преобразует указатель с типом int(*)[3], со значением "указатель на нулевой элемент массива a —a[0]".
reinterpret_cast<int*>(a) определён как static_cast<int*>(static_cast<void*>(a)) https://timsong-cpp.github.io/... ret.cast#7
Каст к void* не меняет значения указателя
Цитата Сообщение от https://timsong-cpp.github.io/cppwp/n4659/conv.ptr#2
A prvalue of type “pointer to cv T”, where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The pointer value is unchanged by this conversion.
Значение по-прежнему "указатель на a[0]".
Про static_cast<int*>(...):
Цитата Сообщение от https://timsong-cpp.github.io/cppwp/n4659/expr.static.cast#13
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion.
Объект b типа T == int, конечно, есть по адресу A, который представляет указатель static_cast<void*>(a). Но объект a[0] типа int[3] не является pointer-interconvertible со своим первым элементом типа int (см. https://timsong-cpp.github.io/... onvertible)
Значит, static_cast<int*>(...) не меняет значения указателя и он по-прежнему указывает на a[0].

Итак, имеем переменную int * pa =reinterpret_cast<int*>(a); с типом int* и значением указатель на a[0].

Теперь к арифметике указателей.
Цитата Сообщение от https://timsong-cpp.github.io/cppwp/n4659/expr.add#4
When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements,86 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined.
Вроде всё в порядке, до тех пор, пока мы прибавляем к pa значения от 0 до 3. pa указывает на a[0], следовательно, pa + 2 указывает на a[2]. Естественно, напрягает тот факт, что указатель с типом int* указывает на объект с типом int[3]. Про это написано чуть ниже
Цитата Сообщение от https://timsong-cpp.github.io/cppwp/n4659/expr.add#6
For addition or subtraction, if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar, the behavior is undefined.
Думаю, даже без заглядывания в определение similar types, ожидаемо, что типы int и int[3] are not similar.

Вот и UB. То, что тут массив двумерен, а там был трёхмерен — не играет существенной роли.
2
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
09.01.2019, 23:40
Цитата Сообщение от Undisputed Посмотреть сообщение
а гарантий нет
С точки зрения C++ гарантий нет. С точки зрения реализации гарантии есть.
Важно понять, что язык, как и его библиотека - это лишь причиндалы, это они подгоняются под платформы, а не наоборот.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
09.01.2019, 23:50
В качестве упражнения можете попробовать найти UB при попытке что-то прочитать через pa (типа int j = *pa;). (Наверное это слишком просто для упражнения).
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
10.01.2019, 00:06
Цитата Сообщение от Undisputed Посмотреть сообщение
Даже несмотря на то, что вы делаете это от имени вспомогательного указателя, это не отменяет тот факт что фактический объект лежащий в памяти по адресу int * pa =reinterpret_cast<int*>(a); это тот самый двумерный массив 3х3,
Оно и не должно отменять этого факта равно как и факта впадения Волги в Каспийское море. Возглас: -"Как бы чего не вышло!" это вечный вопрос. Но он может здорово навредить. При запоре, например.
Указатель на определённый байт, является переменной хранящей его адрес. Тип значения по указателю не тип одномерного массива int[3] а это тип int и это значит, что индекс исходного массива равно как и подмассивов тут вообще не причём. Просто указатель указывает на первый элемент. И пользуясь индексированием по указателю - мы имеем законное право пройти хоть всю память. Но мы идём лишь до последнего элемента. Что не так? Стрикт алиайзинг? Сам компилятор пользуется адресной арифметикой.
Я не имел ввиду такие экзотические типы как bool (обычно 1 байт) и не думаю, что выравнивание как-то может помешать. Это потому, что размер массива всегда равен n*sizeof(T) если количество элементов n (независимо от количества измерений), а Т - тип конечного элемента.

Добавлено через 10 минут
Цитата Сообщение от rat0r Посмотреть сообщение
Естественно, напрягает тот факт, что указатель с типом int* указывает на объект с типом int[3]
Указатель на int об этом не догадывается и ему-то, как раз, не нужно слабительное.
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
10.01.2019, 00:09
Цитата Сообщение от IGPIGP Посмотреть сообщение
При запоре, например.
Цитата Сообщение от IGPIGP Посмотреть сообщение
ему-то, как раз, не нужно слабительное
Пожалуйста, найди себе форум по интересам для демонстрации своей копрофилии.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
10.01.2019, 00:28
Цитата Сообщение от rat0r Посмотреть сообщение
Пожалуйста, найди себе форум по интересам для демонстрации своей копрофилии.
Вот уж не стану угождать вашим интересам. За новое слово - спасибо, прогуглил и нахожу его удачным для описания ситуации. Тема изрядно загажена, - да. Однако, в вашей терминологии, - мы с вами на одном поле не копрофилировали и прошу на вы обращайтесь.
Что касается некорректности обращения к адресному пространству массива через указатель на его первый элемент - не убедительно. Вообще.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
10.01.2019, 12:22
Всё-таки нужно сделать финальное уточнение. UB ещё до выхода за границы наступает в C++17. До C++17 UB будет из-за выхода за границы.
0
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
10.01.2019, 13:13
Цитата Сообщение от rat0r Посмотреть сообщение
даже без заглядывания в определение similar types, ожидаемо, что
Указатель гуляет по элементам двух-мерного массива типа int.
Так что очень даже similar

Ещё, ожидаемо, что двух-мерный массив : int a[][3] ={ {1,2,3}, {4,5,6}, {7,8,9} };
будет хранить свои элементы в памяти именно в такой последовательности,
в какой они указанны при инициализации.
Вот так: один за другим, в одном непрерывном блоке памяти.

Ещё, ожидаемо, что указатель:
int* pa =reinterpret_cast<int*>(a);
Будет указывать на первый элемент двух-мерного массива.

И теперь, почитав внимательно раздел 8.7 Additive operators,
Вы верно поймете, что указатель p1:

C++
1
2
3
int a[][3] ={ {1,2,3}, {4,5,6}, {7,8,9} }; 
int* pa =reinterpret_cast<int*>(a);
int* p1 = pa + 3;
обязан указывать на элемент со значением 4

поведение определено:
по адресу, который хранит p1 обязан находиться объект типа int, со значением 4.

Добавлено через 2 минуты
Цитата Сообщение от rat0r Посмотреть сообщение
До C++17 UB будет из-за выхода за границы.

Я понимаю, что некоторые люди - альтернативно одаренные.
Мыслят каким то странным образом.

Всё же, где вы там увидели выход за пределы диапазона?

Добавлено через 21 минуту
Цитата Сообщение от IGPIGP Посмотреть сообщение
И пользуясь индексированием по указателю - мы имеем законное право пройти хоть всю память.
Это не законно

Чужую память даже просто читать нельзя,
без риска нарваться на access violation

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
std::string s1("abc");
const std::string s2("abc");
//до C++11
char x = s1[s1.size()];//UB
char x = s2[s2.size()];//Ok
почему это для константной строки OK, а для мутабельной UB??
1
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
10.01.2019, 13:29
Цитата Сообщение от eva2326 Посмотреть сообщение
почему это для константной строки OK, а для мутабельной UB?
Потому что это C++
С++03
21.3.4 basic_string element access
C++
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
Returns: If pos < size(), returns data()[pos]. Otherwise, if pos == size(), the const
version returns charT(). Otherwise, the behavior is undefined.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,095
10.01.2019, 13:44
Цитата Сообщение от Undisputed Посмотреть сообщение
Если в коде есть место неопределенному поведению то программа фактически не валидная.
Ничего подобного! Это значит что программа при каких-то условиях может стать невалидной. Скажем, переполнение знаковых чисел формально UB, но оно часто используется, поскольку упрощает код.
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
А раз реализация не полностью соответствует стандарту, то стоит ли полагаться только на стандарт?
Проблема в том, что в разных компиляторах разные баги. Да и в более новых версиях баги исправляются и поведение компилятора притягивают к стандарту.
Цитата Сообщение от Undisputed Посмотреть сообщение
Вот это UB можно, а то нельзя?
Любое UB можно если знаешь что делаешь. Проблемы начнутся при портировании, обновлении компилятора и тому подобном. Уверены что такого не произойдет или преимущества от UB перекрывают риск - вперед. Но здесь, на форуме, UB лучше не допускать из педагогических соображений.
Цитата Сообщение от Undisputed Посмотреть сообщение
фактический объект лежащий в памяти по адресу int * pa =reinterpret_cast<int*>(a); это тот самый двумерный массив 3х3
После приведения к указателю "UB", связанные с массивом, уже неактуальны. Можете попытаться привязаться к выходу за пределы памяти, но тоже вряд ли что выйдет: там выделено 3x3x(sizeof(int)) байт.
Примерно этим пользуются при вызове функций memset(), memcpy() и т.п.: неважно сколько измерений у массива, это просто непрерывный блок байтов.
Цитата Сообщение от eva2326 Посмотреть сообщение
Это не законно
Чужую память даже просто читать нельзя,
без риска нарваться на access violation
Как раз для Си законно, он оперирует непрерывной моделью памяти, целиком доступной одному процессу. Access violation вызывается не программой, а операционкой.
.
Ну и вернусь немного назад во времени чтобы разобраться с порядком хранения элементов в многомерном массиве. Похоже, моя первая модель была неудачной, попробую другую:
C
1
2
3
4
5
struct Arr{
  int elem[Y];
};
struct Arr arr[X];
arr[x].elem[y] = z;
То есть формирование массива идет не слева направо как я думал (int arr[X])[Y], а справа налево. При объявлении массива это выглядит странновато, зато при обращении к элементу вполне логично.
0
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
10.01.2019, 13:58
Цитата Сообщение от Croessmah Посмотреть сообщение
const_reference
Цитата Сообщение от Croessmah Посмотреть сообщение
if pos == size(), the const
version returns charT()
Хотите сказать, что с++03 предписывает возвращать ссылку на локальный объект? ))
Это же UB.

Есть ссылочка на pdf?
(C++03: N1577, N1655, N1733)
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
10.01.2019, 14:08
Цитата Сообщение от eva2326 Посмотреть сообщение
Хотите сказать, что с++03 предписывает возвращать ссылку на локальный объект?
Зачем локальный? Есть же статические.
return *"";
Ну и, скорее всего, там в любом случае есть нолик в конце строки.
Не выделять же каждый раз память под c_str,
поэтому return data[pos] будет нормально работать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.01.2019, 14:08

В чем разница между массивом строк и List<string>?
А есть ли принципиальная разница между string array1 и List&lt;string&gt; array2 ? И если есть, то в чем она заключается?

Разница между статическим и экземплярным методом
В книге уже несколько раз встречается понятие статического и экземплярного метода, но не поясняется конкретно, в чем между ними разница,...

В чем разница между простым линейным списком, и динамическим линейным списком?
вопрос в теме

Разница между массивом структур и очередью
Поясните пожалуйста разницу между массивом структур и очередью.

VPN не подключается со статическим IP-адресом (ошибка 720), с динамическим — все работает
Всем привет! В магазине имеется VPN соединение подключающееся к серверу на складе. При получении ip-адреса автоматически подключение...


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

Или воспользуйтесь поиском по форуму:
140
Ответ Создать тему
Новые блоги и статьи
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. Сразу отвечу: А в PvP с ним. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru