Чи слід вчити своїх учнів аллоке? [зачинено]


18

Наскільки широко використовується allocaв реальному світі? Чи слід вчити своїх учнів користуватися, allocaколи це має сенс? Або я повинен навчити їх ніколи не користуватися цим? Виходячи з фону C ++ RAII, ідея не вимагати виклику freeвручну звучить багатообіцяюче, особливо у функціях з кількома точками виходу.



8
Чому б не навчити їх V99 VLA?

@cnicutar alloca () залежить від реалізації, але принаймні багато реалізацій повертають NULL після відмови. V99 VLA не можуть вказати на збій.
Складні дивіться біографію

2
@sbi: Тому ТАК це відкрите запитання, яке насправді не відповідає формату того, що закриваючі вважають повідомленнями SO. Це занадто суб'єктивно, немає чітко вираженої відповіді, просто думка. Що добре, але не для ТА. Зауважте також, що з поваги до представника ОП ніхто не проголосує, ми просто закриваємо це питання поза темою.
Пол Сасик

1
@PascalCuoq У будь-якому разі не слід виділяти багато з алока / VLA. Якщо ви не впевнені, що "багато" в поточному контексті, використовуйте malloc.

Відповіді:


31

Якщо ви проводите курс загального програмування на С, ви не повинні навчати їх тому, що не відповідає стандарту. Програмісти-початківці без необхідності писати нестандартний та / або не портативний код, тому що їх навчали таким чином, були величезною проблемою для індустрії програмного забезпечення протягом останніх 20-30 років. Вартість того, що вони не навчають їх стандарту, і нічого, крім стандарту, ймовірно, астрономічні.

Якщо ви тримаєте вдосконалений курс з алгоритмів або програмування додатків, можливо, було б добре згадати його. З іншого боку, я програмував все, починаючи від жорстких вбудованих додатків у реальному часі до потоку програм для Windows протягом 15 років, не використовуючи жодної функції.


Єдине використання, яке я бачив там, де не було б краще зробити інший спосіб, - це виявлення стек-скришу в деяких версіях Windows, де невдача в виділенні вказала недостатньо місця на місці - або, можливо, у нього був просто якийсь загальний ASM, щоб зловити аварію. ; минув час, коли я подивився на цей код. Це спрацювало, але було трохи жаху.
Стипендіати Дональ

13

Я бачу, як відбуваються дві речі:

  1. Учні розуміють вплив alloca, читають про відмінності між стеком та купами та allocaуважно використовують . (навряд чи)

  2. Студенти думають, що "ось так, mallocне турбуючись про free", використовуйте його надмірно, отримуйте переповнення стека та не майте уявлення, що відбувається.

Я думаю, що набагато краще, якщо ви опишете alloca, а потім запустіть цей код:

#include <malloc.h>

int OverflowMyStack(int start) {
    if (start == 0)
        return 0;

    char * p = (char *)_alloca(4096);
    *p = '0';
    return OverflowMyStack(start - 1);
}

int main () {
    return OverflowMyStack(512);
} 

Джерело: http://www.strchr.com/alloca

покажіть їм небезпеку, а потім скажіть їм не користуватися цим. Вони все одно дізнаються про стек проти кучі, побачать небезпеку в дії та зможуть рухатись за допомогою стандартних матеріалів.


1
Я думаю, що більшість студентів все ще потрапляють у другу категорію навіть після того, як показують їм приклад коду.
праворуч

@WTP - Мабуть, але саме тому ви говорите їм не використовувати це навіть після того, як покажете їм, що може статися.
BlackJack

4
Чому цей код використовується, _allocaа не alloca? І чому це дає результат?
Кіт Томпсон

5

Відповідь на це питання має ґрунтуватися на тому, які ваші цілі стоять в першу чергу.

Ви хочете навчити когось, хто вже знає, як програмувати, як писати С та працювати з існуючим кодом С у дикій природі? Якщо так, то розкажіть про алока та все, що завгодно.

З іншого боку, якщо ви викладаєте вступний курс, який використовує лише C за збігом обставин (а оскільки C - це дуже мала мова тощо), вам слід зосередитись на важливих частинах (написанні модульних програм, підпрограм, колекцій ... .). З точки зору студента, аллока - це зайве, оскільки малок в більшості випадків достатньо, і з точки зору хорошого коду вам краще чітко згадати, як дратує ручне управління пам’яттю та як інші мови вирішують цю проблему. Зрештою, є більше речі для управління пам'яттю, то аллока або RAII, так що ви дійсно не повинні обмежувати себе цим і, як ви вже згадували, набагато простіше зрозуміти мету аллока, якщо порівнювати його з іншими "більш стандартними" способами робити речі іншими мовами (або C99 ...)


2

Ні.

Єдиною причиною, коли програміст C навіть повинен знати про існування аллоки, - це зрозуміти та виправити застарілий код, який він використовує.

Будь-яке використання - allocaце будь-яке

  1. Марно, тобто його можна тривіально замінити змінними фіксованого розміру тривалості автоматичного зберігання, АБО
  2. Небезпечний перелив стека чекає, що трапиться.

Крім кількох продуманих експериментів, для яких я жодного разу не знайшов прикладів у реальному світі, немає жодного випадку використання alloca(або VLA), який не є ні марним, ні вразливим (один із вищезазначених 2 випадків).


2
Звичайно, абсолютно ніхто ніколи не міг би її відповідально використати. Ні ніколи.
DeadMG

Єдине "відповідальне" використання - allocце 100% еквівалент автоматичних масивів фіксованого розміру і менш портативних.
R .. GitHub СТОП ДОПОМОГАТИ

Я гадаю, що ніхто ніколи не міг захотіти виділити якусь динамічну суму, скажімо, кілька кілобайт, яка ніколи не переллється. Або зателефонуйте до якоїсь функції API OS, яка підкаже, скільки їх доступно. Або просто збільшити розмір стека на багато.
DeadMG

Якщо це кілька кб, і ви впевнені, що у вас є кілька кб, ви можете просто використовувати T foo[5000];або будь-що інше.
R .. GitHub СТОП ДОПОМОГАТИ

Тільки якщо T має тривіальний конструктор за замовчуванням. Якби я потребував продуктивності, навіть просте обнулення пам'яті може коштувати мені. Але інші типи можуть мати ще більш складну логіку побудови за замовчуванням. Якщо б я хотів, наприклад, динамічно створити масив std::mutex, я міг би викликати виклик ядра та комутатор контексту для п'яти тисяч мутексів. Не дешево. Не кажучи вже про додаткову вартість кешу розміщення локальних змінних після масиву.
DeadMG

1

На мою думку, не рекомендуйте використовувати його, якщо ви не навчаєте принципам компілятора низького рівня, який використовується для розподілу простору стеку для локальних змінних. Навчіть це в цьому контексті.


0

Документація GCC має кілька практичних плюсів і мінусів alloca(). З практичної точки зору, пристойна кількість вільного програмного забезпечення використовує його, тому добре розуміти, як воно працює і де воно використовується в існуючому коді.

Передача -Wl,-stack=нового розміру стека gcc збільшує максимальний розмір стека; вам потрібно буде це зробити, якщо ваш проект використовує alloca()або виділяє великі тимчасові масиви або використовує рекурсію, яка проходить певну глибину, залежну від контексту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.