Массив динамических объектов (динамический массив объектов)))
- Войдите на сайт для отправки комментариев
Доброго времени суток!
Комрады, направьте на путь истинный, как правильно описать динамический массив.
Я сделал так:
Есть структура
struct TRule { byte SceneID; byte ElseSceneID; };
Задаю массив
TRule* Rule[MAX_RULES];
Когда необходимо создаю элемент в массиве
Rule[RuleID] = new TRule; Rule[RuleID]->SceneID = JRule["ExecuteScene"]; Rule[RuleID]->ElseSceneID = JRule["ElseScene"];
Когда элемент больше не нужен убиваю его
delete Rule[Index];
Вроде все законно, но есть проблема, после 2-3 итерации одного и того же элемента массива в пямять на его место записываются другие данные и МК виснет.
Выяснил это опытным путем, выводя в монитор при создании элемента массива Rule[RuleID]->SceneID. В какой-то момент он перестает быть нулем и я получаю то, что получаю.
Вопрос собственно один, правильно ли я создаю динамический массив? Делал сам по аналогии с теми примерами, что нашел в инете, но там речь шла про отдельные элементы, а не про массив. (http://mypractic.ru/urok-15-ukazateli-v-c-dlya-arduino-preobrazovanie-ra...)
здесь чел расписал рабочие примеры, а дальше ему объясняют как работает магия делете
http://www.cyberforum.ru/cpp-builder/thread780240.html
Вопрос собственно один, правильно ли я создаю динамический массив?
А почитать доку/книгу? Выделили память для элемента через new - освободили через delete, а для массива еще и [] в обоих случаях. Для delete внутрь [] кол-во не указываем.
gonzales, элементы JRule, на которые ваш массив ссылается - не забываете чистить перед delete7
да, спасибо!
но там вопрос немного о другом, удалается весь массив!!! Но прочитав я начинаю понимать, что изначально походу неправильно мыслю.
Если не трудно, прокомментируйте, как изящнее решить следующую задачу.
На SD-карте хранится инфа об объекте в структурированных txt файлах. Я не знаю заранее, сколько объектов в определенный момент времени будет одновременно использоваться, есть только ограничение сверху (заведомо большое). Выделять память под все объекты - пустая трата ресурсов, потому как реально объектов может быть 3 или 5. При этом я должен иметь возможность обратиться к каждому из элементов. Я для удобстра использовал структуру и (видимо наивно) полагал, что динамический массив позволит мне выделять память под конкретный объект и затем ее освободить. Но походу delete затирает весь массив, а не отдельный элемент. Как быть в такой ситуации?
Вопрос собственно один, правильно ли я создаю динамический массив?
А почитать доку/книгу? Выделили память для элемента через new - освободили через delete, а для массива еще и [] в обоих случаях. Для delete внутрь [] кол-во не указываем.
Не понятно написали, new, delete - сдесь все понятно, а что подразумевается под "а для массива еще и [] в обоих случаях. Для delete внутрь [] кол-во не указываем"???
gonzales, элементы JRule, на которые ваш массив ссылается - не забываете чистить перед delete7
Они вычищаются сразу после создания элемента
Не понятно написали, new, delete - сдесь все понятно, а что подразумевается под "а для массива еще и [] в обоих случаях. Для delete внутрь [] кол-во не указываем"???
просто сделай, как по ссылке, что я дал - нет смысла перечислять бока, что ты напорол.
На SD-карте хранится инфа об объекте в структурированных txt файлах. Я не знаю заранее, сколько объектов в определенный момент времени будет одновременно использоваться, есть только ограничение сверху (заведомо большое). Выделять память под все объекты - пустая трата ресурсов, потому как реально объектов может быть 3 или 5. При этом я должен иметь возможность обратиться к каждому из элементов. Я для удобстра использовал структуру и (видимо наивно) полагал, что динамический массив позволит мне выделять память под конкретный объект и затем ее освободить. Но походу delete затирает весь массив, а не отдельный элемент. Как быть в такой ситуации?
Да вы почти все сделали правильно, вам только массив обьектов нужно отделить от самих обьектов.
1. Описать структуру или класс для обьектов.
2. При появлении нового обьекта - память под каждый обьект выделять динамически.
3. В массиве хранить только ссылку на обьект. Массив можно сделать статическим, ибо даже 10-20 ссылок - это совсем немного байт.
4. Когда нужда в обьекте отпадает - чистите сам обьект, удаляете ссылку на него из массива (заменяете на NULL) и удаляете обьект
Они вычищаются сразу после создания элемента
принято это делать "ДО"
На SD-карте хранится инфа об объекте в структурированных txt файлах. Я не знаю заранее, сколько объектов в определенный момент времени будет одновременно использоваться, есть только ограничение сверху (заведомо большое). Выделять память под все объекты - пустая трата ресурсов, потому как реально объектов может быть 3 или 5. При этом я должен иметь возможность обратиться к каждому из элементов. Я для удобстра использовал структуру и (видимо наивно) полагал, что динамический массив позволит мне выделять память под конкретный объект и затем ее освободить. Но походу delete затирает весь массив, а не отдельный элемент. Как быть в такой ситуации?
Да вы почти все сделали правильно, вам только массив обьектов нужно отделить от самих обьектов.
1. Описать структуру или класс для обьектов.
2. При появлении нового обьекта - память под каждый обьект выделять динамически.
3. В массиве хранить только ссылку на обьект. Массив можно сделать статическим, ибо даже 10-20 ссылок - это совсем немного байт.
4. Когда нужда в обьекте отпадает - чистите сам обьект, удаляете ссылку на него из массива (заменяете на NULL) и удаляете обьект
Я в общем-то думал, что именно так я и делаю. Структура есть, память выделяется динамически оператором new. Из того что я прочитал, я вынес, что диначеский массив - это и есть массив указателей. Если не затруднит, подскажите, как правильно описать объект и массив со ссылками
Не понятно написали, new, delete - сдесь все понятно, а что подразумевается под "а для массива еще и [] в обоих случаях. Для delete внутрь [] кол-во не указываем"???
просто сделай, как по ссылке, что я дал - нет смысла перечислять бока, что ты напорол.
Что именно сделать? Удалить весь массив delete [] TRule, так мне это не надо. Я хочу удалить объект, чтобы он не съедал память и ссылку на него в массиве
Пока Вы не покажете код, разговор будет ни о чём.
Код в первом посте. Вопрос в основном теоретический, как сделать правильно.
Код в первом посте.
Это не код, а огрызки. Хотите нормального разговора, давайте код, а если так - потрындеть ...
.del
На SD-карте хранится инфа об объекте в структурированных txt файлах. Я не знаю заранее, сколько объектов в определенный момент времени будет одновременно использоваться, есть только ограничение сверху (заведомо большое). Выделять память под все объекты - пустая трата ресурсов, потому как реально объектов может быть 3 или 5. При этом я должен иметь возможность обратиться к каждому из элементов. Я для удобстра использовал структуру и (видимо наивно) полагал, что динамический массив позволит мне выделять память под конкретный объект и затем ее освободить. Но походу delete затирает весь массив, а не отдельный элемент. Как быть в такой ситуации?
В такой ситуации вместо массива используют список. В каждой структуре хранят указатель на другую/другие структуру. Например http://victor192007.narod.ru/files/cpp_d1.html
По ходу сам нашел.
Как писал b707 нужно удалить ссылку на объект в массиве.
По крайней мере у меня такая конструкция работает абсолютно корректно
По ходу сам нашел.
Как писал b707 нужно удалить ссылку на объект в массиве.
По крайней мере у меня такая конструкция работает абсолютно корректно
Простите, с чего Вы взяли, что она работает? Никакая память здесь не освобождается, объект остаётся в памяти. Ошибки нет, т.к. освобождение NULL - законная опреация, но она просто ничего не делает. Возьмите, наконец, MemoryExplorer и посмотрите, что творится у Вас с памятью.
Я вчера Вам писал, чтобы Вы дали нормальный код и реально собирался поработать и помочь Вам. Но кода Вы не даёте (не знаю почему), дело Ваше.
Но кода Вы не даёте (не знаю почему), дело Ваше.
я запретил публиковать в общий доступ секретные российские разработки. О_О
По ходу сам нашел.
Как писал b707 нужно удалить ссылку на объект в массиве.
По крайней мере у меня такая конструкция работает абсолютно корректно
Простите, с чего Вы взяли, что она работает? Никакая память здесь не освобождается, объект остаётся в памяти. Ошибки нет, т.к. освобождение NULL - законная опреация, но она просто ничего не делает. Возьмите, наконец, MemoryExplorer и посмотрите, что творится у Вас с памятью.
Я вчера Вам писал, чтобы Вы дали нормальный код и реально собирался поработать и помочь Вам. Но кода Вы не даёте (не знаю почему), дело Ваше.
Нормальный код 20000 строк на 25 вкладках))))
Решил добить тему, заодно вдруг кому пригодится.
Вот тестовый код
Как видно, действительно память не освобождается. (((
Странно, но даже единичный объект не удаляется из памяти или memoryFree не правильно работает
а если строчки
51
Rule[3] = NULL;
52
delete [] Rule[3];
местами поменять? и скопки [] выкинуть?
Блин, ошибся, пока писал
Наоборот, сначала убиваем объект, потом вытираем ссылку.
Вот рабочий код
Всем спасибо!!!
Надеюсь, описанный пример будет полезен другим участникам соревнований
скобки после delete не нужны. Ты не массив удаляешь, а структурку.
Уже поправил, хотя так тоже отрабатывало, но скобки конечно не правильно
Наоборот, сначала убиваем объект, потом вытираем ссылку.
А зачем? Зачем вообще строка 54? На что она влияет? Открою Вам страшный секрет - она лишняя. Тоже о строке 36.
Вы неправильно походите к делу и потому работаете вслепую. То, что Вы где-то взяли memoryFree - это шаг в правильном направлении, но на самом деле Вам нужно сделать две вещи:
1. Использовать конструктор и деструктор Вашего объекта для печати информации о его создании / уничтожении. Вы удивитесь насколько легче станет жить, если открыть глаза и не работать вслепую.
2. Использовать не memoryFree, а полноценный монитор памяти.
Собственно даже только с первым пунктом Вы бы давно отладились - привыкайте работать с открытми глазами, не зажмуривайте их от страха.
Мне не очень понятен смысл фразы "память действительно не освобождается". Если Вы хотели, чтобы память при возвращении в пул обнулялась, то таки да, этого не делается но и не должно, так что ручками.
А вот для того, чтобы не использовать занятие и освобождение памяти, добавлена возможность создавать массивы переменного размера - то, что Вам надо, с главным условием - в момент создания массива Вы должны знать его размер.
Мне не очень понятен смысл фразы "память действительно не освобождается".
она не возвращается в алиэкспрес.
Наоборот, сначала убиваем объект, потом вытираем ссылку.
А зачем? Зачем вообще строка 54? На что она влияет? Открою Вам страшный секрет - она лишняя. Тоже о строке 36.
Вы неправильно походите к делу и потому работаете вслепую. То, что Вы где-то взяли memoryFree - это шаг в правильном направлении, но на самом деле Вам нужно сделать две вещи:
1. Использовать конструктор и деструктор Вашего объекта для печати информации о его создании / уничтожении. Вы удивитесь насколько легче станет жить, если открыть глаза и не работать вслепую.
2. Использовать не memoryFree, а полноценный монитор памяти.
Собственно даже только с первым пунктом Вы бы давно отладились - привыкайте работать с открытми глазами, не зажмуривайте их от страха.
я так подозреваю, именно это Вы называли выше реальной помощью, такой "батя в здании" подошел и похлопал по плечу, "не ссы пацан, открой глаза и прыгай"!!!
По существу
1. Если строки 54 и 36 не нужны, возьмите код
и запустите. я с этого начал пост, что просто delete работает наполовину!!!
2. Накой мне полноценный монитор памяти? Чем конкретно плох memoryFree?
3. Страшная тайна, new и delete это и есть конструктор и деструктор, только тссс!!!
PS. Не люблю холивар, но уж как-то совсем все плохо. Особенно товарищ с "алиэкспрессом" порадовал, верх профессионализма
3. Страшная тайна, new и delete это и есть конструктор и деструктор, только тссс!!!
Никому такова не говори больше, это не совсем так. Вернее, совсем не так.
3. Страшная тайна, new и delete это и есть конструктор и деструктор, только тссс!!!
Никому такова не говори больше, это не совсем так. Вернее, совсем не так.
Есть ли ссылка на какой-нить RTFM по этому поводу?
эти функции, несколько сложнее, чем просто вызов конструктора и деструктора.
RTFM -> труп Страуса. Прям вот самый штонинаесть первоисточник.
3. Страшная тайна, new и delete это и есть конструктор и деструктор, только тссс!!!
ты не совсем точно понял смысл рекомендации - пропиши в структуру конструктор и деструктор, функциями которых будет печать("конструктор запущен"), печать("деструктор запущен").
чиста для удобства отладки - потом закомментишь.
Не люблю холивар...
а, придётся... О_О
Я может конечно безгранично туп, но вот вырезка из MSDN
Как видим в конструкторе используется оператор new, а в деструкторе delete. (мопед не мой, я просто разместил объяву)
Но только это все для классов, мне зачем такие сложности, если тут просто структура? И какой смысл делать отдельный конструктор, если мне, чтобы убедиться, что объект создан достаточно того, что я вижу изменение используемой памяти, ну или на крайняк после создания объекта и присвоения значений вывести в монитор Serial.println(Rule[3]->SceneID);
Как видим в конструкторе используется оператор new, а в деструкторе delete. (мопед не мой, я просто разместил объяву)
при чём здесь утилизация переменных класса к отладке твоего кода?
мне зачем такие сложности, если тут просто структура?
да хоть Путин - как ты узнаешь, что делетнул его, если не видишь - упал или стоит?
я так подозреваю, именно это Вы называли выше реальной помощью, такой "батя в здании"
Не понял о чём это. Какой мой пост Вы имеете в виду?
я с этого начал пост
Неправда, Вы начали свой пост с того, что НЕ опубликовали законченный скетч, а я просто умолял Вас, ну опубликуйте же скетч, я хочу Вам помочь, но без законченного скетча это невожно! (мои посты #12 и #15)
2. Накой мне полноценный монитор памяти? Чем конкретно плох memoryFree?
Если Бы Вы его хотя бы раз запустили, этого вопроса бы не было. Но Вы советов не слушаете, они Вам не нужны. Я вот не понимаю "накой" Вы вообще сюда пришли, если знаете лучше нас что Вам "накой", а что "не накой"?
Примите галаперидольчику и прекратите бредить.
Здесь все старожилы знают, что у меня сложные отношения с этим "товарищем", но это наши с ним разборки. Что же до Вас, то, по части "профессионализма", Вам до него как до Луны. Если Вы реально хотите чему-то научиться, а не прокачать понты, то Вам лучше задавать таким людям вежливые вопросы и внимательно слушать ответы, а не задирать хвост "накой мне".
По существу
Ну, а по существу. Обычно, после постов в таком тоне, как был у Вас, я отсылаю человека к универсальной документации на все случаи жизни и ухожу из темы, но вот именно Вам мне почему-то реально хочется помочь, хотя, вроде, и не должно бы. Не знаю почему, считайте это капризом. Я объясню Вам Вашу ошибку реально и серьёзно. Правда при этом не буду выбирать выражений. Хотите учиться - учитесь, хотите обижаться - обижайтесь, дело Ваше.
Итак, долгожданный код, о котором я Вас дважды просил.
Вы, видимо решили, что освобождение памяти не работает на том основании, что условие в строке 46 остаётся истинным. Это бред сивой кобылы. Это условие - это НЕ проверка факта освобождения памяти.
В Rule[3] находится адрес некоторого куска памяти. Вы туда его (адрес) поместили, когда объект создавали. Он (адрес) находится там независимо от того занята эта память или свободна. Вы можете уже освободить память, но адрес (освобождённого куска) там остаётся. Так что Ваша строка 46 ровным счётом ничего не проверяет, от слова "совсем".
Если Вы действительно хотите проверить факт особождения памяти, то слушайте что Вам говорят, а не пытайтесь учить профессионалов что такое конструктор и деструктор. Смотрите, как это делается. Я переписываю Ваш код добавив туда конструктор и деструктор о которых я говорил:
Теперь при каждом создании объекта я вижу, что он создаётся и вижу его адрес. А при удалении объекта, я также вижу адрес удаляемого объекта. Смотрим:
Видим, что несмотря на Вашу грязную ругань, объекты создаются и удаляются на одном и том же месте, т.е. память никуда не девается, всё работает как часы.
Теперь я позволю себе поудалять из кода глупости с присваиванием NULL и Вашу бредовую проверку
Смотрим, что получается
Видим, что память как была 1552 в начале, так и остаётся после каждого удаления объекта. Объект постоянно создаётся на одном и том же месте - по адресу 742, значит это место аккуратно освобождается и каждый раз оно же выделяется для вновь создаваемого объекта.
Вы согласны. что всё работает как часы? Думаю, оно у Вас и работало нормально, просто Вы придумали какой-то бред, считая его проверкой и на основании этого бреда запаниковали. Если бы Вы ещё вчера показали мне код, как я Вас просил, проблема бы уже давно забылась бы!
Теперь я готов ответить на Ваши вопросы, но вежливые и по делу, т.е. продолжить нормальную профессиональную беседу. При любом наезде или попытке поучить меня, что такое конструктор, Вы будете посланы туда, куда я обычно в таких случаях посылаю (Выше об этом было). И никакого холивара не будет. У нас разные весовые категории.
Как видим в конструкторе используется оператор new, а в деструкторе delete. (мопед не мой, я просто разместил объяву)
А ещё и там, и там используется оператор if и что с того? Делаем вывод, что if - это и есть конструктор (и деструктор заодно)?
Но только это все для классов, мне зачем такие сложности, если тут просто структура?
Структура (struct) - такой же точно класс как и class. Разница только в умолчательный аттрибутах методов и свойств.
Я может конечно безгранично туп,
Не знаю, туп ты или не туп, но то, что очень мало знаешь, и при этом хамоват - это точно.
PS. Не люблю холивар, но уж как-то совсем все плохо. Особенно товарищ с "алиэкспрессом" порадовал, верх профессионализма
Это хороше что порадовал "алиэкспрессом", проффесиональный подход из #17 вам ведь оказался совершенно неинтересен. Значить бум развлекатся, писать говнокод, холиварить о конструкторе ))) Пятница ведь!