Например, для фиктивной функции write(int length, const char* text){...}
Есть ли разница в показателях памяти между этими двумя подходами?
write(18,"The cake is a lie.");
или же
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt)
Бонус: что если есть какое-то повторение? то есть цикл вызывает функцию несколько раз, используя массив, элементы которого являются предполагаемыми аргументами.
Я задаю этот вопрос, особенно бонус, в надежде лучше понять, как каждый из них использует память, чтобы оптимизировать мою эффективность при записи на чувствительных к памяти платформах, таких как Arduino. Тем не менее, если вы знаете еще более эффективный способ, пожалуйста, поделитесь! Спасибо!
Это зависит от того, char txt[19]
объявлен в объем функции или в глобальной области (или пространстве имен).
Если в рамках функции, то txt
будет размещен в стеке и инициализирован во время выполнения из копии строковый литерал Находясь в (только для чтения) сегмент данных.
Если в глобальном масштабе, то он будет размещен во время сборки в сегменте данных.
Бонус: если он размещен в какой-то дополнительной области, например в теле цикла, то вы должны предполагать, что он будет инициализироваться во время каждой итерации цикла (оптимизатор может делать некоторые трюки, но не рассчитывать на это).
Пример 1:
int len = 18;
char txt[19] = "The cake is a lie.";
int main() {
write(len,txt);
}
Вот len
( int
) а также txt
(19 байт + выравнивание выравнивания) будет выделено в сегменте данных программы во время сборки.
Пример 2:
int main() {
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt);
}
Здесь строковый литерал "The cake is a lie."
будет размещен в сегменте данных программы во время сборки. К тому же, len
а также txt
(19 байт + заполнение) может быть выделено в стеке во время выполнения. Оптимизатор может опустить len
распределение и, возможно, даже txt
, но не рассчитывайте на это, так как это будет зависеть от многих факторов, таких как write
Тело доступно, что именно он делает, качество оптимизатора и т. д. В случае сомнений, смотреть в сгенерированном коде (godbolt теперь поддерживает цели AVR).
Пример 3:
int main() {
write(18,"The cake is a lie.");
}
Здесь строковый литерал "The cake is a lie."
будет размещен в сегменте данных программы во время сборки. 18
будет встроен в код программы.
Поскольку вы разрабатываете на AVR, стоит упомянуть некоторые дополнительные особенности, а именно, исполняемый файл приложения изначально хранится в вспышка, и как только вы «запускаете» его, он копируется в оперативную память. Можно избежать копирования в ОЗУ и сохранить данные во Flash, используя PROGMEM
ключевое слово (хотя, чтобы сделать что-либо значимое с данными, вам нужно будет скопировать их в оперативную память).
Других решений пока нет …