Проблема с объемом памяти в структуре
Я работаю над проектом, в котором мне нужно создать ИК-программу, которая работает со всеми платами AVR/Arduino для управления ИК-устройствами, такими как телевизор, DVD и т. д. Я создаю структуру, которая может нести Pronto информация о коде, и это то, что у меня есть до сих пор:
struct Pronto {
char* code;
public:
Pronto(){}
Pronto(char* code) {
bool isValid = validateProntoCode(code);
if(isValid)
this->code = code;
}
Pronto toPronto(char* code) {
Pronto cde(code);
return cde;
}
void setPronto(char* code){
bool isValid = validateProntoCode(code);
if(isValid)
this->code = code;
}
char* toString(){
return code;
}
private:
bool validateProntoCode(char* code) {
if(!isInHex(code[strlen(code)-1]))
return false;
for (int i = 0; i < strlen(code); i++) {
if (!isInHex(code[i]) && !(i % 5 == 4 ))
return false;
if (i % 5 == 4 && code[i] != ' ')
return false;
if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
return false;
}
return true;
}
bool isInHex(char c) {
char list[22] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
for (int i = 0; i < 22; i++) {
if (c == list[i])
return true;
}
return false;
}
};
Этот код структуры Я могу установить код Pronto, проверить его и получить из него строковое значение. Теперь всякий раз, когда я объявляю структуру внутри Arduino IDE:
pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");
Я получаю следующее сообщение:
Sketch использует 4082 байта (12%) места для хранения программ. Максимальный размер – 32 256 байт.
Глобальные переменные используют 2137 байт (104 %) динамической памяти, а для локальных переменных остается -89 байт. Максимальный размер – 2048 байт.
Недостаточно памяти; см. http://www.arduino.cc/en/Guide/Troubleshooting#size советы по уменьшению ваш след.
Изображения:
https://prnt.sc/ohu4d9
https://prnt.sc/ohu4io
https://prnt.sc/ohu4m8
https://prnt.sc/ohu4pr
https://prnt.sc/ohu4tn
По сути, я просто показал всю свою работу над кодом, который я сделал. Я закомментировал все глобальные вары, ничего не изменилось. НО, когда я комментирую "pronto.setPronto("0000 0000");", я получаю свободное место.
Итак, как я могу изменить эту структуру, чтобы она не занимала много места?
Правильный код char*? Это проблема. Теперь вы можете помочь мне изменить код или, по крайней мере, сказать мне, как я могу решить эту проблему.
@Alex Zhuravel, 👍-1
Обсуждение2 ответа
На основе вашего вопроса я подготовил новый скетч (один файл), чтобы проверить проблему.
Код:
struct Pronto {
char* code;
public:
Pronto() {}
Pronto(char* code) {
bool isValid = validateProntoCode(code);
if (isValid)
this->code = code;
}
Pronto toPronto(char* code) {
Pronto cde(code);
return cde;
}
void setPronto(char* code) {
bool isValid = validateProntoCode(code);
if (isValid)
this->code = code;
}
char* toString() {
return code;
}
private:
bool validateProntoCode(char* code) {
if (!isInHex(code[strlen(code) - 1]))
return false;
for (int i = 0; i < strlen(code); i++) {
if (!isInHex(code[i]) && !(i % 5 == 4 ))
return false;
if (i % 5 == 4 && code[i] != ' ')
return false;
if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
return false;
}
return true;
}
bool isInHex(char c) {
char list[22] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'};
for (int i = 0; i < 22; i++) {
if (c == list[i])
return true;
}
return false;
}
};
Pronto pronto;
void setup() {
pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");
}
void loop() {}
Процедура проверки для ATmega328P возвращает:
D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino: In function 'void setup()':
D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino:50:71: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");
^
Sketch uses 844 bytes (2%) of program storage space. Maximum is 30720 bytes.
Global variables use 83 bytes (4%) of dynamic memory, leaving 1965 bytes for local variables. Maximum is 2048 bytes.
Можете ли вы проверить, сохраняется ли проблема с этим скетчом файла? Возможно, вы установили и связали библиотеку, которая выделяет много глобальных переменных.
На снимках экрана вы используете строковые литералы, которые намного длиннее, чем в вашем примере кода. Я подозреваю, что использование PROGMEM может быть способом обойти проблему. Но зачем возиться с постоянными строками, проверять и преобразовывать их во время выполнения, а не хранить их как необработанные данные? (Кроме того, результат проверки константного строкового литерала всегда будет одним и тем же. Поэтому рассмотрите возможность удаления проверки вашего производственного кода.)
uint16_t myParsedProntoCode[] = {
0x0000, 0x006D, 0x0000, 0x00BF, 0x009F, 0x0031, 0x0030, 0x0010, 0x0010, 0x0031
};
Это намного эффективнее, так как для хранения полубайта (4 бита) требуется всего 4 бита вместо 8 бит. Так что только половина пробела, даже не принимая во внимание бессмысленные пробелы.
Большое спасибо, теперь он экономит больше места., @Alex Zhuravel
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Инициализация массива структур
- Отправить структуру через Serial
- Передавать данные структуры во внешнюю структуру через serial?
- Как получить размер (sizeof) массива структур
- Структура typedef не работает
- Как уменьшить размер скетча?
- Собственное определение типа с использованием структуры не дает имени типу
Сама структура не занимает много места, я вижу в основном сам код с 40 байтами. В сообщении говорится, что ваши глобальные переменные занимают 104% памяти. Проблема есть, но вы не показали нам свои глобальные переменные. Может быть, вы можете уменьшить количество глобальных переменных, когда их не нужно объявлять во время выполнения всей программы., @chrisl
Я сделал. Когда я закомментирую "pronto.setPronto("0000 0000");", я получаю больше свободного места. Но все #define, #include и другие глобальные переменные, которые я закомментировал, ничего не изменилось. Я собираюсь добавить URL-адрес с фотографиями в пост, чтобы показать вам., @Alex Zhuravel
Эм, а какой длины там протокод? Это определенно намного длиннее, чем в вашем вопросе., @chrisl
Это не имеет значения, код Pronto может быть сколь угодно длинным. Вы знаете, что это правильно? Все, что я сделал, это сохранил строку кода Pronto в переменной char*. Я не мог использовать строку или ее библиотеку, так как заголовок не позволял мне. В итоге я использовал char*., @Alex Zhuravel
Вы храните код в глобальной переменной, так что да, имеет значение, насколько он велик. У вас есть только 2 КБ, @chrisl