Освобождение памяти
- Войдите на сайт для отправки комментариев
Вс, 02/09/2018 - 23:38
Всем привет!
У меня есть два класса - "PROB" и "BORP".
Я создаю объект класса "PROB", который содержит в себе поле класса "BORP". А потом удаляю его. Между этими действиями я смотрю сколько оперативной памяти свободно. И получается так, что после удаления объекта памяти остается меньше, чем до создания объекта. То есть при удалении объекта освобождается не вся память и я не понимаю почему.
Скетч:
int freeRam () { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); } class BORP { public: String nameItem; boolean flagUseSwitchItem; byte COUNTSWITCHITEM; String *nameSwitchItem = new String[1]; byte switchPosition; byte myIndexSwitch; byte STARTX; void Init(byte index) { switch (index) { case 0: myIndexSwitch = index; COUNTSWITCHITEM = 2; nameSwitchItem = new String[COUNTSWITCHITEM]; nameSwitchItem[0] = "off"; nameSwitchItem[1] = "on"; switchPosition = 0; STARTX = 130; break; case 1: myIndexSwitch = index; COUNTSWITCHITEM = 3; nameSwitchItem = new String[COUNTSWITCHITEM]; nameSwitchItem[0] = "Low"; nameSwitchItem[1] = "Med"; nameSwitchItem[2] = "Hi"; switchPosition = 0; STARTX = 130; break; } } ~BORP() { delete[] nameSwitchItem; } }; class PROB { public: byte myIndexMenu; byte COUNTITEM; BORP *masItem = new BORP[1]; byte cursorPosition; byte MAXLINE; byte STARTX; byte STARTY; byte BETWEENY; byte STARTPOINTX; byte STARTPOINTY; PROB(byte index) //Индекс комнаты: 1 - Menu; 2 - Bluetooth; 3 - Memory Options; 4 - Measurements. { switch (index) { case 0: myIndexMenu = index; COUNTITEM = 2; masItem = new BORP[COUNTITEM]; //Увеличиваем размер массива. masItem[0].nameItem = "Item 0"; masItem[0].flagUseSwitchItem = false; masItem[1].nameItem = "Item 1"; masItem[1].flagUseSwitchItem = false; cursorPosition = 0; MAXLINE = COUNTITEM; STARTX = 30; STARTY = 10; BETWEENY = 10; STARTPOINTX = 10; STARTPOINTY = 10; break; case 1: myIndexMenu = index; COUNTITEM = 5; masItem = new BORP[COUNTITEM]; //Увеличиваем размер массива. masItem[0].nameItem = "Item 0"; masItem[0].flagUseSwitchItem = true; masItem[0].Init(0); masItem[1].nameItem = "Item 1"; masItem[1].flagUseSwitchItem = false; masItem[2].nameItem = "Item 2"; masItem[2].flagUseSwitchItem = false; masItem[3].nameItem = "Item 3"; masItem[3].flagUseSwitchItem = true; masItem[3].Init(1); masItem[4].nameItem = "Item 4"; masItem[4].flagUseSwitchItem = false; cursorPosition = 0; MAXLINE = COUNTITEM; STARTX = 30; STARTY = 10; BETWEENY = 10; STARTPOINTX = 10; STARTPOINTY = 10; break; } } ~PROB() { delete[] masItem; } }; void setup() { Serial.begin(9600); while (!Serial) {} Serial.println(freeRam()); delay(500); PROB obj(1); delay(500); Serial.println(freeRam()); delay(500); delete &obj; delay(500); Serial.println(freeRam()); delay(500); } void loop() { }
В мониторе порта отображается следующее:
2328 - осталось памяти до создания объекта
2030 - осталось памяти после создания объекта
2163 - осталось памяти после удаления объекта
То есть 165 не освобождается. Почему так происходит?
Что-то я вообще не понял. Указатель на String завели, а потом с какого перепуку он стал массивом строк? Да еще берете в указатель адрес созданного объекта String в #16, потом в #28 кладете в него адрес другого стринга, а первоначальный объект где повисает?
Что-то я вообще не понял. Указатель на String завели, а потом с какого перепуку он стал массивом строк? Да еще берете в указатель адрес созданного объекта String в #16, потом в #28 кладете в него адрес другого стринга, а первоначальный объект где повисает?
Я думал, что так выделяется динамическая память для массива строк. Просто количество элементов этого массива изначально неизвестно, поэтому я пишу в поле класса:
А потом уже увеличиваю его до нужного значения:
Как по-другому сделать я не знаю(
Динамических массивов, по-моему, в Ардуину не завозили (хотя, могу и ошибаться), поэтому лично я при необходимости динамики пользуюсь дедовским одно- или дву-направленным списком.
Да еще берете в указатель адрес созданного объекта String в #16, потом в #28 кладете в него адрес другого стринга, а первоначальный объект где повисает?
Спасибо за наводку на ошибку. Сделал освобождение памяти перед тем, как задать новый размер (#28, #38, #76, #91) и теперь вся отлично!
Спасибо за наводку на ошибку. Сделал освобождение памяти перед тем, как задать новый размер (#28, #38, #76, #91) и теперь вся отлично!
Только непонятно зачем.
Да и не единственная это ошибка. Что у Вас написално в строке 129? Кто Ва учил так освобождать память объекта, созданного не в куче?
Сделайте там нормальное освобождение и просто не запрашивайте ничего в строках 16 и 60. Примерно вот так:
А вообще, об этой ошибке Вас компилятор предупредил, посто у Вас выключены его предупреждения. Включите и никогда не выключайте.
Динамических массивов, по-моему, в Ардуину не завозили (хотя, могу и ошибаться)
Таки ошибаетесь
Даже const в первой строке необязателен, можно убрать.
Ну так это обычный локальный. Я имел в виду такие, как в языках типа пэхэпэ - делай туда push() и не думай о размерности.
Для данного языка и такой за счастье :)
Для "не думать о размерности" есть контейнеры в STL, "but кому это здесь нужно?"
Для "не думать о размерности" есть контейнеры в STL
О_О А чо, так можно было?
Спасибо за наводку на ошибку. Сделал освобождение памяти перед тем, как задать новый размер (#28, #38, #76, #91) и теперь вся отлично!
Только непонятно зачем.
Да и не единственная это ошибка. Что у Вас написално в строке 129? Кто Ва учил так освобождать память объекта, созданного не в куче?
Сделайте там нормальное освобождение и просто не запрашивайте ничего в строках 16 и 60. Примерно вот так:
А вообще, об этой ошибке Вас компилятор предупредил, посто у Вас выключены его предупреждения. Включите и никогда не выключайте.
Спасибо большое за исправления!
Единственное только не понял что делают фигурные скобки без оператора. Они нужны, чтобы просто обозначить блок и лучше был виден кусок кода? В документации не нашел ничего об этом.
Ааа, кажется понял: это что-то типа функции. В теле функции создается объект, а когда из этой функции выходим, объект естественно удаляется, так как внутри функции был создан (локальный).
Ааа, кажется понял: это что-то типа функции. В теле функции создается объект, а когда из этой функции выходим, объект естественно удаляется, так как внутри функции был создан (локальный).
Без обид, но может - лучше для начала таки почитать книжку по С/С++?
Ааа, кажется понял: это что-то типа функции. В теле функции создается объект, а когда из этой функции выходим, объект естественно удаляется, так как внутри функции был создан (локальный).
Без обид, но может - лучше для начала таки почитать книжку по С/С++?
Надо бы, но хочу быстренько этот проект сделать. Я понимаю, что и классы у меня организованны криво и не мастер я c++, но потихоньку изучаю, учусь на ошибках.
Ну суть фигурных скобок я примерно правильно описал или нет?
Ну суть фигурных скобок я примерно правильно описал или нет?
Нет. Правильная суть - в книжках по С/С++.
Со скобками у меня почему-то в монитор порта потом ничего не выводится. То есть после скобки ничего не работает, в том числе и вывод свободной памяти.
Ну суть фигурных скобок я примерно правильно описал или нет?
поясните - где там вообще фигурные скобки без оператора?
Ну суть фигурных скобок я примерно правильно описал или нет?
поясните - где там вообще фигурные скобки без оператора?
Со скобками у меня почему-то в монитор порта потом ничего не выводится. То есть после скобки ничего не работает, в том числе и вывод свободной памяти.
Вы думаете, я выложил не проверяя? Всё у Вас выводится. Возможно надо скорость в мониторе порта поставить такую же как стоит в Serial.begin (у меня не такая, как у Вас была)
Со скобками у меня почему-то в монитор порта потом ничего не выводится. То есть после скобки ничего не работает, в том числе и вывод свободной памяти.
Вы думаете, я выложил не проверяя? Всё у Вас выводится. Возможно надо скорость в мониторе порта поставить такую же как стоит в Serial.begin (у меня не такая, как у Вас была)
Для теста полностью ваш код скопировал - все равно не выводит. Может быть у меня старая IDE/компилятор, сейчас посмотрю.
Обновил - то же самое.
У меня всё выводит. Я вообще-то про скорости писал. Вы их выставили?
У меня всё выводит. Я вообще-то про скорости писал. Вы их выставили?
Да-да, выставил "57600". Пробовал менять, но ничего. Очень странно, конечно.
Взял из поста и попробовал ещё раз (думал, мож при вставке чего поломалось) - всё нормально работает.
В таком случае, Вам в посте #12 всё правильно сказали, рано Вам ещё. Почитайте матчасть, помигайте светодиодами, а то Вы сейчас даже готовый скетч запустить не можете, начинайте с начала, а варианты типа
Обычно не срабатывают.
Ни фига Вы не понимаете, но постарайтесь понять, что начинать надо с нуля, а не сразу со сложных проектов.