Оператор New.

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
Провокационны пост и вопрос, спору нет. В этом разделе предлагаю для обсуждения.
Даже не знаю с чего начать...

Скажем так, многие считают, что "так называемые динамические массивы" должны создаваться, всенепременно с оператором new.
А некоторые персонажи всерьез (не безосновательно) считают что динамических массивов в С++ не существует вовсе. По достаточно просто причине, что в поле класса мы не можем создать массив произвольной величины. Так как все поля должны быть объявлены до запуска конструктора... И создать массив мы можем только с предустановленной[константно] величиной.

Ну это скажем так первый момент.

Второй момент заключается в ошибке компилятора, у которого возникают сомнения о том что массив может быть инициализирован нулевым значением. Это(гипотетически) возможно, если размер массива мы передаем аргументом функции или метода. Указатель массива не может (быть нулевым)то есть указывать на самого себя, тут вопросов нет.
И если мы попытаемся перевести то что нам пишет компилятор, то окажется что он не может индентифицировать массив(так как есть сомнения что указатель указывает на самого себя).

Фикус в том, что при создании динамического массива, следуя указанием компилятора, мы можем увеличить безызвестную переменную X на +1 и тем самым в корне исключим ситуацию когда ссылка на первый элемент массива будет ссылается на самого себя.

И все тут вроде хорошо и отлично, но персонажи в тырнете, считают, или даже скажем точнее они обходят данную ошибку, тем что создают указатель, и указателю присваивают указатель на массив. Ну не без оператора new. И все это воспроизводится, что именно так, а ни как иначе должен создаваться динамически массив.
И этому посвящено ну множество страниц в ключе оператора new. При том что как мне кажется, они даже в далеке не понимают смысла оператора new/


Если у кого-то есть мнение, такое или иное, я предлагаю обсудить :)
 

rkit

★★★✩✩✩✩
5 Фев 2021
508
127
Чё? В C++ есть std::vector, сделавший всё вышенаписанное нерелевантным бредом уже больше 20 лет назад.
 

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Если у кого-то есть мнение, такое или иное, я предлагаю обсудить
Пока если не мнение, то ощущение, что вы ничегошеньки не понимаете в том, о чем пишете.

Второй момент заключается в ошибке компилятора,
Что за ошибка? Приведите пример кода и сообщения об ошибке
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,972
632
45
Скажем так, многие считают, что "так называемые динамические массивы" должны создаваться, всенепременно с оператором new.
А что говорит стандарт языка?

Ну, если уж вам нужен "массив" с динамическим размером, с которым можно делать все что угодно, то используйте list: https://learn.microsoft.com/ru-ru/cpp/standard-library/list-class
 

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Автор явно путает "массив динамического размера" и "массив в динамической памяти"
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@bort707,

Я ничего не путаю. Не надо за меня что-то додумывать.


А что говорит стандарт языка?
Давайте спросим иначе у стандарта языка. А какое практическое применение у оператора new? ( По вашему мнению)

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

Но стоит вам загуглить... И вам станет совершенно очевидно, что вся эта ....относительно оператора new совершенно не из воздуха берется. Помимо интернета, мы можем столкнуться и с книжными убеждениями.


Чё? В C++ есть std::vector, сделавший всё вышенаписанное нерелевантным бредом уже больше 20 лет назад.
При чем тут vector? Тебе нечего было написать? Обсуждается оператор new. Ты читать разучился? Или нажал ответить в другой теме?
 
Изменено:

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
ну и забористая дурь... давайте нитроген и ркит, жгите! Побольше "тыканий" и бесммысленных каках друг в друга - как раз для флудики, я запасся попкорном.
Ну дык я продолжаю ;)

Немного дополню "все-та-ки" о динамических массивах. Упомянул я их не просто так, а потому что в большинстве случаев "( во всех )" упоминаний оператора new, в пример приводятся именно подобные массивы, размер которого мы можем определить аргументом при входе в метод или функцию.

То есть мы без проблем пишем:

void foo (int a) // Создаем функцию
{
int arr [a]; // Создаем массив размерность которого мы передали в функцию.
}

И всё круто, всё компилируется. Всё компилируется в Аrduino IDE. Компилируется в Аtmel Studio... И работает разумеется. Не всегда правда. А когда аргумент а становится = 0, то начинают возникать проблемы.

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

Но если мы попытаемся скомпилировать данный код например в Code::Block ( а мы и там можем запилить код для avr), а там по умолчанию стоят значительно более суровые условия компиляции. Компилятор выдает ошибку:

variable -sized object 'arr' may not by initialized


Чтобы детально разобраться почему возникает ошибка, нужно разбирать ассемблерный код.
Но я могу предположить, что при создании обычной переменной, например int (2 бата) указатель стека увеличивается на 2. При создании массива, указатель стека увеличивается на [x]. Если х =0, то возникают проблемы, и они реально возникают. Не готов объяснить их причину. Видимо адрес следующей переменной совпадает с адресом массива. Либо указатель, а массив это указатель на первый элемент, начинает ссылаться на самого себя.

Но не суть важно. Беседы мы ведем только с компилятором и лишь он является авторитетом.

На основе всего написанного, я надеюсь очевидно, мы можем создать массив переменного размера указав при инициализации
int arr [a+1];
То есть создаем массив как минимум с одной ячейкой.

У внимательного читателя может возникнуть справедливый вопрос, а каким боком ко всему этому имеет оператор new ???

Если мы откроем образовательные сайты или книжки по си в разделе динамические массивы или динамическое выделение памяти,
то нам предложат при создании подобных массивов, создать сперва указатель

int *p

а потом присвоить ему...

p = new int [a];

И далее работать как с обычным массивом. И обмана тут нет, по другому его не создать, с пометкой new.

Кое кто считает, что new это для передачи массива далее (я натыкался на такие заключения). Но мы и обычный массив можем передать по указателю. И за пределы блока он в любом случае не выйдет. Внутри блока мы можем вызвать функцию или метод передать им указатель на массив, но когда блок закроется, закроется и массив с пометкой new, даже без delete. Мы тупо не можем сослаться на него, точнее на созданный на него указатель, за пределами блока.

Для сохранения переменной или массива, у нас есть static...

Возникает вполне резонный вопрос, а если всё работает и без new на кой ляд он тогда вообще нужен?

Это один из вопросов темы ;)

Потому как пока это выглядит как история племени, которое обнаружило во время охоты металлический обруч и принесло его шаману, который его в руках покрутил, повертел... И изрек: "Дык епт! Его на голову надевать надо!"

Или правильно писать одевать...
 
Изменено:

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
асм, нью, Сишные массивы - смешались люди, кони... ух!
@Nitrogenium вы это чисто из теоритеческого интереса упражняетесь?
new - англицким по белому написано, используется для инициализации динамических объектов. Сишный массив это частный случай.
Для них даже отдельно указано all dimensions... must be specified as positive, ноль не является положительным целым. И вся эта болтология о том что там компилятор может/не может не более чем вариации фантазий на тему undefined behavior.
 
  • Лойс +1
Реакции: poty

Геннадий П

★★★★★★✩
14 Апр 2021
1,972
632
45
Я уже потерял нить о чем автор темы хотел сказать или доказать, или просто поболтать.

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

И да автор темы, видать, не сталкивался с более высокоуровневыми языками, типа C# в котором новые объекты просто обязывают определять через "new". Если ему на столько влом каждую новую переменную определять через "new", то пусть в питонисты или похожие идет.
 
  • Лойс +1
Реакции: poty

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Если х =0, то возникают проблемы, и они реально возникают
Кто-нибудь из читателей может мне объяснить, зачем создавать массив нулевой длины? О чем это чудо вообще?
Кое кто считает, что new это для передачи массива далее (я натыкался на такие заключения). Но мы и обычный массив можем передать по указателю. И за пределы блока он в любом случае не выйдет.
Нитроген, вы троллите что-ли?
Если указатель глобальный, то массив, созданный new , продолжит существовать и после выхода программы из блока, в то время как время жизни "обычного массива", в любом случае ограничена локальной областью действия.
 
Изменено:
  • Лойс +1
Реакции: poty

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Внутри блока мы можем вызвать функцию или метод передать им указатель на массив, но когда блок закроется, закроется и массив с пометкой new, даже без delete.
не закроется. Почему бы вам не почитать учебник, прежде чем выступать на форуме с подобной чушью?
мы тупо не можем сослаться на него, точнее на созданный на него указатель, за пределами блока.
Бред.
Область действия динамического массива соответствует области действия указателя. Если указатель глобальный, то созданный в локальном блоке массив будет существовать до конца работы программы, или пока мы явно не вызовем delete
 

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Нитроген, чтобы прекратить этот балаган, ответьте мне на простой вопрос. Одинакова ли область действия массива в двух вариантах кода ниже.
C++:
int* p;
{
p = new int[a];
}
и
C++:
int* p;
{
int b[a];
p = b;
}
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
vortigont

Я же привел приер что динамические массивы спокойно инициализируются без new.

Вы можете лично в этом убедиться.

bort707 Смотри.... У массива нет области действия. Есть область видимости массива, но ты походу до этого еще не доехал...


Геннадий П
Если бы я обсуждал С# или другие высокоуровневые языки, я бы сделал как минимум отметку, наверное это было бы правильно. Спаведливо?
Вы Си# хотели обсудить? Это в другой ветке.
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
3,235
942
@Nitrogenium, у массива есть и область видимости и время существования. В примере с new указатель p определён вне блока, он существует независимо от него. Область памяти, на которую указывает p, создаётся в куче и будет сохранена после выхода из блока (автоматически delete не вызовется).
Во втором примере указатель p определён вне блока, он существует независимо от него. Но массив определён внутри блока, он создастся в стеке и будет уничтожен после выхода из блока. Указатель p будет указывать на область памяти, коnорая массивом уже не является, там может быть записано всё, что угодно.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,972
632
45
Есть у кого установленный компилятор с дебаггером?
Предлагаю посмотреть в какие машинные коды компилируется выделение массива с new и без него.
А до этого это спор ради спора, особенно с таким потоком сознания как у топикстартера. Или я опять не понял о чем тема разговора.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
Кто-нибудь из читателей может мне объяснить, зачем создавать массив нулевой длины? О чем это чудо вообще?
Очевидно что не за чем. Но если бы вы реально что-то кодили, вам бы было совершенно очевидно, что при некоторых условиях, некоторая формула может принять нулевое значение.
 
Изменено:

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@Nitrogenium, у массива есть и область видимости и время существования. В примере с new указатель p определён вне блока, он существует независимо от него. Область памяти, на которую указывает p, создаётся в куче и будет сохранена после выхода из блока (автоматически delete не вызовется).
Во втором примере указатель p определён вне блока, он существует независимо от него. Но массив определён внутри блока, он создастся в стеке и будет уничтожен после выхода из блока. Указатель p будет указывать на область памяти, коnорая массивом уже не является, там может быть записано всё, что угодно.

Каким образом вы будете ссылаться (читать/писать) в массив вне блока?

Область памяти будет сохранена, когда мы укажем static

Когда скобочка } закрывается,
умирает всё что было внутри.

Бредовые примеры на которые вы ссылаетесь, если что, не мои :)
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
3,235
942
@Nitrogenium, так первый пример как раз и позволяет ссылаться на массив вне блока.
некоторая формула может принять нулевое значение
так обрабатывайте это в коде.
static не позволит делать массивы изменяемого размера.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@Nitrogenium, так первый пример как раз и позволяет ссылаться на массив вне блока.
Потому что он создан вне блока, или по каким-то другим причинам?

static не позволит делать массивы изменяемого размера.
С одной стороны жаль, а с другой... А нахрена?
 

poty

★★★★★★✩
19 Фев 2020
3,235
942
Потому что он создан вне блока, или по каким-то другим причинам?
Потому что поведение (в частности, выделение памяти) для new отличается от динамического выделения памяти для локальных переменных.
static - это переменная с локальной видимостью, но глобальным временем жизни.
Это уж решать программисту. Но сводить свои узкие интересы к необходимости или нет для других программистов тоже не стоит.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@poty,
Потому что поведение (в частности, выделение памяти) для new отличается от динамического выделения памяти для локальных переменных.
Ну я надеюсь, что перед тем как это изречь всё это проверил. Ну чтобы не вводить в заблуждение читателей. Я так понимаю?

Сперва мы можем логически подумать, а в какой области new выделяет память... может в EEPROM??? А???

А если на компе, то наверное сразу в swap области?

А мы можем создать переменную, и посмотреть её адрес? А следом создать еще одну, но уже с пометкой new, и посмотреть её адрес, и сделать выводы? А потом создать без new и тоже сравнить?

Тут даже ассемблерный код не потребуется.
 

poty

★★★★★★✩
19 Фев 2020
3,235
942
@Nitrogenium, о "местах выделения памяти" - читайте доки по тем МП или процессорам, которые применяете. (про EEPROM - самому-то не смешно?)
Проверять за Вас не буду, хотите - проверяйте. Я хоть и не профи (сейчас) в программировании, но и не новичок, реализованных проектов хватает, прописные истины проверять не собираюсь, нет ни времени, ни желания.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
У волшебника Сулеймана всё по честному и без обмана! ;)

Изначально было объявлено что провокационный пост. Берегите нервы!
 

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Каким образом вы будете ссылаться (читать/писать) в массив вне блока?
Через указатель.

Когда скобочка } закрывается,
умирает всё что было внутри.
Сударь, очевидно что вся эта тема возникла только потому, что вы плохо знаете С. Динамический массив, созданный через new, не умирает.

Я ведь не просто так написал два этих примера. Это именно та разница, которая отвечает на главный вопрос топика, но вы ее не догоняете.
 
Изменено: