Нужно ли объявлять массивы как статические локальные переменные? - PullRequest
0 голосов
/ 24 января 2019

Допустим, у меня есть функция, которую я называю партией, в которой есть массив:

char foo[LENGTH];

В зависимости от значения LENGTH это может быть дорого распределять каждый раз, когда функцияназывается.Я видел:

static char foo[LENGTH];

Так что он выделяется только один раз, и этот массив всегда используется: https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

Это лучший метод для массивов?

РЕДАКТИРОВАТЬ:

Я видел несколько ответов, что статические локальные не лучшие.Но как насчет стоимости инициализации?Что если бы я позвонил:

char foo[LENGTH] = "lorem ipsum";

Разве это не придется копировать каждый раз, когда я вызываю функцию?

Ответы [ 3 ]

0 голосов
/ 24 января 2019

«Выделение» объекта с примитивным типом данных и с автоматической продолжительностью хранения обычно не имеет большого значения.Вопрос больше: хотите ли вы, чтобы содержимое foo выдерживало выполнение функции или нет?

Рассмотрим, например, следующую функцию:

char* bar() {
   char foo[LENGTH];
   strcpy(foo, "Hello!");
   return foo;  // returning a pointer to a local variable; undefined behaviour if someone will use it.
}

В этомcase, foo выйдет из области видимости и не будет (юридически) доступен после завершения bar.

Однако все в порядке, если вы напишите

char* bar() {
   static char foo[LENGTH];
   strcpy(foo, "Hello!");
   return foo;  // foo has static storage duration and will be destroyed at the end of your program (not at the end of bar())
}

Может возникнуть проблема с большими переменными с автоматической продолжительностью хранения, если они станут такими большими, что они превысят (ограниченный) стекразмер, или если вы вызываете функцию рекурсивно.Однако, чтобы преодолеть эту проблему, вам нужно вместо этого использовать динамическое выделение памяти (т. Е. New / delete).

0 голосов
/ 24 января 2019

Во-первых, время для автоматического выделения массива char не зависит от его размера, и от любой разумной реализации есть постоянная временная сложность увеличения указателя стека, которая является сверхбыстрой.Обратите внимание, что это будет то же самое даже для VLA (которые недопустимы в C ++), только это приращение будет операндом времени выполнения.Также обратите внимание, что ответ будет другим, если ваш массив будет инициализирован.

Так что действительно неясно, на какой недостаток производительности вы ссылаетесь.

С другой стороны, если вы сделаетеВ указанном массиве static вы не понесли бы никакого наказания в предоставленном примере - поскольку char не инициализируется, не будет нормальной синхронизации, которая препятствует двойной инициализации статических переменных.Однако ваша функция (вероятно) станет поточно-небезопасной.

Итог: преждевременная оптимизация - корень зла.

0 голосов
/ 24 января 2019

Поскольку LENGTH должна быть постоянной времени компиляции (C ++, нет C99 VLA), foo просто собирается использовать пространство в стеке. Очень быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...