Размер статического массива можно менять в процессе выполнения программы

Согласно правильному ответу в Статический массив против динамического массива в C ++ статические массивы имеют фиксированные размеры.

Тем не менее, это компилируется и работает просто отлично:

int main(int argc, char** argv)

Означает ли это, что размер статического массива можно изменить?

Решение

Вы на самом деле не увеличиваете массив. Давайте посмотрим ваш код подробно:

int myArray[2]; myArray[0] = 0; myArray[1] = 1;

Вы создаете массив из двух позиций с индексами от 0 до 1. Пока все хорошо.

myArray[4];

Вы получаете доступ к пятому элементу в массиве (элемент, который, безусловно, не существует в массиве). Это неопределенное поведение: все может случиться. Вы ничего не делаете с этим элементом, но это не важно.

myArray[2] = 2; myArray[3] = 3;

Теперь вы получаете доступ к элементам три и четыре и меняете их значения. Опять же, это неопределенное поведение. Вы меняете ячейки памяти рядом с созданным массивом, но «больше ничего». Массив остается прежним.

Массив объектов класса. Динамический. Статический. Создание Особенности. ООП C++ Для начинающих #96

На самом деле, вы можете проверить размер массива, выполнив:

std::cout

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

В C ++ границы массивов не проверяются. Вы не получили ни ошибки, ни предупреждения в основном из-за этого. Но опять же, доступ к элементам за пределами массива является неопределенным поведением. Неопределенное поведение означает, что это ошибка, которая может появиться не сразу. Даже программа, очевидно, может закончиться без проблем.

Читайте также:
Программа для настройки сети cisco

Надеюсь это поможет.

Другие решения

Нет, в аду нет шансов. Все, что вы сделали, — это незаконный доступ к нему за его пределами. Тот факт, что это не приводит к ошибке для вас, совершенно не имеет значения. Это полностью UB.

Во-первых, это не статический массив, это массив, выделенный в автоматическое хранение.

myArray[4];

не является новым объявлением, это отброшенное чтение из элемента # 4 ранее объявленного двухэлементного массива — неопределенное поведение.

Задания, которые следуют

myArray[2] = 2; myArray[3] = 3;

запись в память, которая не выделена для вашей программы — также неопределенное поведение.

Источник: web-answers.ru

Статический массив. Структура, его преимущества и недостатки

Задание размера статического массива run-time значением

К чему может привести, или вообще ни к чему не приведёт, задание размера статического массива значением, которое станет известно лишь на этапе выполнения программы? Знаю лишь то, что это не по стандарту языка C++ , в C это вполне себе законно. Примером будет выступать вот такой код:

int main() < int n; std::cin >> n; T arr[n]; /*код, включающий в себя работу с массивом arr*/ return 0; >
Отслеживать
user206435
задан 24 окт 2019 в 21:02
157 7 7 бронзовых знаков

В си это не законно, это просто расширения компиляторов которые позволяют так делать. С GCC этот код компилируется, однако не под всеми версиями, а компилятор от майкрософт, честно вам отдаст ошибку. Для C++ есть вектор, которому вы можете прямо во время выполнения менять размер, при помощи метода resize .

MQL4 программирование — Массивы и циклы

– user206435
24 окт 2019 в 21:35

Вектора использовать умею. Дело в том, что на недавнем уроке информатики моему классу рассказывали о том, что не пишите так, мол, программа даже если компилируется, то будет работать неправильно. Я возразил, что это лишь будет код, написанный в несогласовании со стандартом языка, т.к. такое утверждение встречал когда-то на этом сайте. Кстати, в мой лицей один человек не попал лишь из-за того, что в письменном экзамене по информатике он написал стат. массив с длиной, вводимой с клавиатуры :). Ещё один вопрос: если всё таки скомпилировалась, то работать будет без никаких undefined behaviour?

Читайте также:
Что значит исполнение программы

24 окт 2019 в 21:50
24 окт 2019 в 22:16

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

В языке С++ такие массивы не поддерживаются

В типичной традиционной реализации VLA в языке C определение локального VLA

T arr[n];

будет втихаря заменено компилятором на два определения локальных переменных

size_t __size_arr; T *arr;

Размер массива будет сохранен во внутренней переменной __size_arr

size_t __size_arr = n;

(то есть таким образом будет запомнено, каким было значение n в тот момент, когда управление проходило по вашему объявлению).

А память для самого массива будет выделена на вершине стека при помощи некоей внутренней платформенно-зависимой функциональности вроде alloca

T *arr = alloca(__size_arr * sizeof(T));

Также, в точке(-ах) выхода из блока, содержащего определение такого массива (таких массивов), компилятор сгенерирует код, возвращающий вершину стека в то положение, в котором она находилась при входе в этот блок, т.е. фактически освобождающий весь стек, выделенный для VLA в этом блоке.

Вычисление размера такого массива через sizeof arr будет порождать выражение вида

__size_arr * sizeof(T)

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

unsigned n = 42; unsigned a[n]; unsigned s = sizeof(*(printf(«Hello Worldn»), // Напечатает «Hello World»

Также, по понятным причинам, компилятор не позволит вам передавать управление ( goto или switch ) в области видимости таких массивов через объявления таких массивов и объявления соответствующих типов

goto skip; // Ошибка: нелегальный `goto` unsigned n = 42; unsigned a[n]; skip:;

Также, язык накладывает определенные ограничения на использование стандартных функций setjmp / longjmp в присутствии VLA.

Источник: ru.stackoverflow.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru