Динамический массив (массив с динамически выделяемой памятью)
- Войдите на сайт для отправки комментариев
Вс, 06/12/2020 - 10:26
Есть ли принципиальная разница в использовании таких конструкций для arr1 и arr2 кроме места, где под них выделяется память? Есть ли подводные камни?
int fun() { int c = 5; return c; } void setup() { int n = fun(); int arr1[n]; // создал массив c динамически выделяемой памятью на стеке int *arr2; arr2 = new int[n]; // здесь тоже, но на куче delete[]arr2; } void loop() {}
Теряешь производительность, проблемы с фрагментацией кучи.
Разница, безусловно, есть, а вот принципиальная она для Вас или нет, решить можете только Вы.
Разница, безусловно, есть, а вот принципиальная она для Вас или нет, решить можете только Вы.
А в каких случаях она может быть принципиальна? Кагбэ вопрос об этом:))
проблемы с фрагментацией кучи.
Объявляется внутри блока - удаляется внутри блока. По идее не должно?
Что такое блок?
Что такое блок?
{}
Программисту удобнее работать со стеком, он очистится сам, при выходе из блока. А на куче delete() нужно вызвать не забыть. Больше никакой разницы, но хороший тон - всегда выбирать путь, на котором возможность накосячить меньше. Ибо вера в свою идеальность и непогрешимость есть грех гордыни! ;))) Смертный грех! Тащемта.
Программисту удобнее работать со стеком, он очистится сам, при выходе из блока. А на куче delete() нужно вызвать не забыть. Больше никакой разницы, но хороший тон - всегда выбирать путь, на котором возможность накосячить меньше.
Спасибо!
Что такое блок?
{}
Почему ты решил, что менеждер кучи знает, где у тебя скобки стоят?
Что такое блок?
{}
Почему ты решил, что менеждер кучи знает, где у тебя скобки стоят?
Цеплючий ты, как репейник и невнимательный! Автор написал что ОН САМ (без ансамбля, лично ..ля) вызвал delete() ДО закрывающей скобки. В том примере, что он написал. И "менеджер кучи"??? Простите, кто? Может быть "старший менеджер"? ;)) (...склонив голову и приподняв монокль)
И почему ты решил, что менеджеру кучи важно, до скобки или после? Впрочем, не напрягайся, как ты не напрягся элементарно погуглить, что это вообще такое, а сходу высказал свое высосанное из пальца особо бесполезное мнение.
Э-э-э сказали мы с Петром Ивановичем ...
Программисту удобнее работать со стеком
Таки да, но есть нюанс ...
возможность накосячить
в случае со стеком существенно выше, а главное, она неконтролируема!
Вот, что будет в случае, если памяти недостаточно?
В варианте с кучей, если писать грамотно (проверять выделилась ли память простым сравнением указателя с nullptr), то ничего страшного, просто проверка даст отрицательный результат и можно предпринять какие-то меры.
А в варианте со стеком никакой простой возможности проверить что и как там выделилось нету (ну не считать же возможностью проверки полноценный мониторинг состояния памяти), просто стек налезет на кучу ... дальше рассказывать?
Ну, и ... для ардуино неважно, но вообще-то вариант со стеком - это расширение GCC - оно не стандартизовано.
Почему ты решил, что менеждер кучи знает, где у тебя скобки стоят?
А почему Вы решили, что в ардуине есть менеджер кучи?
Ну, и ... для ардуино неважно, но вообще-то вариант со стеком - это расширение GCC - оно не стандартизовано.
Но в одном из своих сообщений вы упомянули стандарт ISO C99. Я его, конечно, не читал, но и не осуждаю:)
Еще один великий знаток подтянулся. Нет менеджера. malloc наугад адрес блоку присваивает. Еще идиотские высказывания будут?
И почему ты решил, что менеджеру кучи важно, до скобки или после? Впрочем, не напрягайся, как ты не напрягся элементарно погуглить, что это вообще такое, а сходу высказал свое высосанное из пальца особо бесполезное мнение.
Еще раз: найди в ардуине менеджер кучи. Не найдешь - втяни уже язык в жопу! И не в ардуине, кстати, тоже. Хамство твое прощается ровно до той поры, пока оно не превосходит твою дремучесть.
Это не Java и не Python, это С++, где все происходит по желанию и под контролем автора. Если не использовать никакого "старшего менеджера кучи", то его и не будет.
До тебя еще не дошло, что даже STL не часть языка программирования?
А так - хочешь менеджера для Ардуино? Флаг в руки - пиши! Я даже уверен в том, есть десятки написанных, если в мусоре гитхаба покопаться. ;)))
В варианте с кучей, если писать грамотно (проверять выделилась ли память простым сравнением указателя с nullptr), то ничего страшного, просто проверка даст отрицательный результат и можно предпринять какие-то меры.
А в варианте со стеком никакой простой возможности проверить что и как там выделилось нету (ну не считать же возможностью проверки полноценный мониторинг состояния памяти), просто стек налезет на кучу ... дальше рассказывать?
Тут соглашусь, но мне кажется, что забыть освободить память - более вероятная ошибка... но это мое ИМХО.
Нет менеджера. malloc наугад адрес блоку присваивает.
Это не менеджер и даже не супервайзер и не эксклюзивный дистрибьютер. Это просто malloc, и его реализация еще у Кернигана и Ричи описана. И никак с тех пор не меняется. Куча == список свободных блоков, в котором выделяется первый подходяшего размера.
А "менеджер" - это интеллектуальное управление кучей, учет ссылок, сбор мусора, перемещение блоков в фоновом режиме, управление режимами перемещяемый/неперемещаемый, и куча других сервисов, зависящих от свойств платформы и фантазии автора.
Но в одном из своих сообщений вы упомянули стандарт ISO C99. Я его, конечно, не читал, но и не осуждаю:)
А Вы точно не путаете С и С++?
Это не менеджер и даже не супервайзер и не эксклюзивный дистрибьютер.
Может он эффективный менеджер? rkit в смысле.
А Вы точно не путаете С и С++?
Возможно и путаю. Серьезно.
Т.е не все фишки, реализованные в С и предусмотренные сишными стандартами должны работать в С++? До этого думал, что ++ это самостоятельный язык, но его основа С, дополненная и расширенная...
Т.е не все фишки, реализованные в С и предусмотренные сишными стандартами должны работать в С++?
Нет, не все.
А в массивах, кстати, там довольно большая разница. Если интересно, посмотрите объявление массивов в С++'17 (на стр. 220) и С'18 (на стр. 106). Как видите, там отличается не только то, что в С разрешены массивы переменной длины, а в С++ - нет. И ещё, если интересно, разберитесь в стандарте С как с такими массивами sozeof работает, тоже интересно :-)
(ссылки на эти стандарты я давал в Песочнице, номера страниц указаны по PDF - они отличаются от тех, что на самих листах написаны)
Как видите, там отличается не только то, что в С разрешены массивы переменной длины, а в С++ - нет.
Спасибо, с этим разобрался - насколько знание язЫков позволило)
И ещё, если интересно, разберитесь в стандарте С как с такими массивами sozeof работает, тоже интересно :-)
А с этим не очень. Единственное, опытным путем определил, что в GCC при создании массива на куче sizeof не работает, вернее показывает размер указателя. А размер массива на стеке sizeof выдает верно.
определил, что в GCC при создании массива на куче sizeof не работает, вернее показывает размер указателя.
так и должно быть, так все компиляторы делают. Массив семантически равен указателю на его первый элемент.
чтобы узнать число элементов массива используют от такую нехитрую консрукцию
T - любой тип
Но с
такой фокус не прокатывает
Но с
такой фокус не прокатывает
А в "чистом" Си с дин. массивом, определенном через malloc, sizeof сработает?
Нет.
в Си массив тоже == указатель на 1 элемент
с другой стороны, когда ты делаешь new T[...] ты уже к тому времени знаешь, скока элементов будет в массиве, число их пишется в скобках вместо многоточия. Это может быть константа или переменная, неважно, можно просто ее сохранить как размер массива.
Нарывался на холивары на других форумах, типа "Оно жишь знает, сколько памяти освободить при вызове
че, Ему жалко вернуть через sizeof?"
И правда, че Ему жалко?:)
Ему не жалко: но как же он может вернуть Вам размер массива, если Вы запрашиваете размер указателя. Ему совесть не позволяет.
Нарывался на холивары на других форумах, типа "Оно жишь знает, сколько памяти освободить при вызове
че, Ему жалко вернуть через sizeof?"
И правда, че Ему жалко?:)
Это от непонимания что такое sizeof и что такое delete. Ему может и не жалко, тока физической возможности не имеет.
Или сделай свой vector для ардуины, с размером, покером и переодетыми стюардессами
Или сделай свой vector для ардуины, с размером, покером и переодетыми стюардессами
Про него вспоминал сто раз, когда решал задачу конкурса. Подскажите вариант удобной и наиболее правильной реализации для Ардуины
Подскажите вариант удобной и наиболее правильной реализации для Ардуины
Мой. :)
Подскажите вариант удобной и наиболее правильной реализации для Ардуины
Мой. :)
Вы слишком скромный:)) Не показываете:))))
Дак он для внутренних нужд. На самом деле не вижу ничего сложного самому написать простейший дин.массив. Надо только определиться с тем, что он должен уметь. Как тока сформулируешь хотелки, напиши их здесь, мы его по шагам и напишем. В лиарьном времени, всем миром навалимся.
Еспрессив (ESP8266 и ESP32) - тоже ардуина и там есть полный STL ;))). Для АВР нужно? - так и говори. У Деда попроси.
У Деда попроси.
Да, выпросишь у него! Он самого писать заставляет! А я на шару хотел выклянчить, готовое:))))
Я тебе предложил всего лишь написать вместе, по твоим хотелкам, как ты его видишь
не вижу ничего сложного самому написать простейший дин.массив. Надо только определиться с тем, что он должен уметь.
вот-вот, главное - определится для чего он нужен, а то может и писать ничего не надо.
Мне в конкурсе ничего кроме malloc() и free не понадобилось
Я тебе предложил всего лишь написать вместе, по твоим хотелкам, как ты его видишь
Я на столько "новичОк", что о std::vector узнал из интернетов (русскоязычных) во время решения задачи конкурса. А Вы предлагаете мне мои хотелки сформулировать.
Хочу "щоб було як отам" и даже лучше. А где это применить - потом придумаю:)
На самом деле мне нужен был всего лишь массив, в который я мог занести значения "на лету" и вернуть мне кол-во этих значений - т.е. надо
и память чтоб не фрагментировал при увеличении размера. Вы мне идею для личного "конкурса" подкинули. Попробую.
и память чтоб не фрагментировал при увеличении размера.
Так не бывает
Так не бывает
Тогда задача облегчается...
Вывод:
6 строчка обьявление массива,
14-16 первоначальное заполнение массива
24 - добавление к нему еще элемента 1000
32 - увеличение размера с сохранением предыдущих данных
Да, все так. Осталась малость - TArray.h написать .
ПС код я понял сразу
ППС 32 строка - создаете новый, переписываете, старый удаляете?
При объявлении массив создаете ровно 8 или с запасом (например 12)?
ППС 32 строка - создаете новый, переписываете, старый удаляете?
Естественно
При объявлении массив создаете ровно 8 или с запасом (например 12)?
ровно 8.
На самом деле, это массив, его переразмещать нужно редко, по самому определению массива. Если нужно добавлять/удалять элементы, надо делать список, длина которого заранее не известна. А там уже можно импровизировать с размерами. Например, в расчете на частое пополнение списка, можно память хапать кратно, допустим, 8 или 16 элементам. Если при очередном пополнении вышел за макс. число элементов, то добавлять естес-сно не 1, а сразу 8-16. Код усложняется не намного