Дуже багато цікавих відповідей на це "старе" питання, навіть деякі відносно нові відповіді, але я не знайшов жодної, яка б це згадувала ....
При правильному та обережному застосуванні послідовне використання alloca()
(можливо, на всьому застосуванні) для обробки невеликих розподілів із змінною довжиною (або C99 VLAs, якщо вони доступні) може призвести до зниження загального зростання стека, ніж інакше еквівалентна реалізація з використанням великих розмірів локальних масивів фіксованої довжини . Тож alloca()
може бути корисним для вашої стеки, якщо ви ретельно використовуєте її.
Я знайшов цю цитату в .... Добре, я склав цю цитату. Але справді, подумайте про це….
@j_random_hacker дуже правий у своїх коментарях під іншими відповідями: Уникнення використання alloca()
на користь негабаритних локальних масивів не робить вашу програму більш безпечною від переповнення стека (якщо тільки ваш компілятор не є достатньо старшим, щоб дозволяти вбудовувати функції, які використовуються. alloca()
У цьому випадку вам слід оновлення або, якщо ви не використовуєте alloca()
всередині циклів, і в цьому випадку вам слід ... не використовувати alloca()
всередині циклів).
Я працював на робочому столі / сервері та вбудованих системах. Багато вбудованих систем взагалі не використовують купу (вони навіть не посилаються на її підтримку) з причин, які включають уявлення про те, що динамічно виділена пам'ять є злою через ризики витоку пам'яті у програмі, яка ніколи коли-небудь перезавантажуватися роками за один раз, або більш розумне обгрунтування того, що динамічна пам’ять небезпечна, оскільки не може бути точно відомо, що програма ніколи не буде фрагментувати свою купу до точки помилкового вичерпання пам'яті. Тому вбудованим програмістам залишається мало альтернатив.
alloca()
(або VLA) можуть бути лише правильним інструментом для роботи.
Я знову бачив час і час, коли програміст робить буфер, виділений стеком, "достатньо великий, щоб обробляти будь-який можливий випадок". У глибоко вкладеному дереві викликів багаторазове використання цього (анти -?) Шаблону призводить до перебільшеного використання стека. (Уявіть дерево викликів глибиною 20 рівнів, де на кожному рівні з різних причин функція сліпо перерозподіляє буфер у 1024 байти "просто для безпечності", коли загалом він буде використовувати лише 16 або менше, і лише в дуже рідкісні випадки можуть використовувати більше.) Альтернатива - використанняalloca()
або VLA та виділити лише стільки простору стеку, скільки потрібно вашій функції, щоб уникнути зайвого навантаження на стек. Будемо сподіватися, що коли одна функція в дереві викликів потребує розподілу більше, ніж зазвичай, інші в дереві викликів все ще використовують свої звичайні невеликі асигнування, і загальне використання стека додатків значно менше, ніж якщо кожна функція сліпо перерозподіляє локальний буфер .
Але якщо ви вирішите використовувати alloca()
...
Виходячи з інших відповідей на цій сторінці, здається, що VLA повинні бути безпечними (вони не з'єднують виділення стеків, якщо викликаються з циклу), але якщо ви використовуєте alloca()
, будьте обережні, щоб не використовувати їх у циклі, і зробіть переконайтеся, що ваша функція не може бути вбудована, якщо є ймовірність, що вона може бути викликана в циклі іншої функції.