Должен ли я учить своих учеников по алике? [закрыто]


18

Насколько широко используется allocaв реальном мире? Должен ли я учить своих учеников использовать, allocaкогда это имеет смысл? Или я должен научить их никогда не использовать это? Исходя из C ++ RAII, идея о том, что нет необходимости вызывать freeвручную, звучит многообещающе, особенно в функциях с несколькими точками выхода.



8
Почему бы не научить их C99 VLA?

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

2
@sbi: Для SO это открытый вопрос, который на самом деле не соответствует формату того, что, по мнению близких, должно быть в SO сообщениях. Это слишком субъективно, четкого ответа нет, просто мнение. Что хорошо, но не для ТАК. Обратите также внимание, что из уважения к представителю ФП никто не голосует против, мы просто закрываем этот вопрос как не по теме.
Пол Сасик

1
@PascalCuoq В любом случае вы не должны выделять много ресурсов с помощью alloca / VLA. Если вы не уверены, что значит «много» в текущем контексте, используйте malloc.

Ответы:


31

Если вы проводите курс по общему программированию на C, вы не должны учить их тому , чего нет в стандарте. Программисты-новички без необходимости писать нестандартный и / или непереносимый код, потому что их учили таким образом, были огромной проблемой для индустрии программного обеспечения в течение последних 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 - Возможно, но именно поэтому вы говорите им не использовать его даже после показа им, что может произойти.
Блэкджек,

4
Почему этот код использует, _allocaа не alloca? И почему это дает результат?
Кит Томпсон

5

Ответ на этот вопрос должен быть основан на том, что ваши цели в первую очередь.

Вы хотите научить кого-то, кто уже знает, как программировать, как писать C и работать с существующим кодом C в дикой природе? Если это так, расскажите о alloca и обо всем, что вы хотите.

С другой стороны, если вы преподаете вводный курс, в котором по совпадению используется только C (а язык C очень маленький и т. Д.), Вам следует сосредоточиться на важных частях (написание модульных программ, подпрограмм, сборников и т. Д.). .). С точки зрения студента, alloca является излишним, так как malloc достаточно в большинстве случаев, и с точки зрения хорошего кода вам лучше явно упомянуть, как ручное управление памятью раздражает и как другие языки справляются с этой проблемой. В конце концов, есть больше что-то для управления памятью, затем alloca или RAII, так что вы действительно не должны ограничивать себя этим, и, как вы уже упоминали, гораздо проще понять назначение alloca, если вы сравните его с другими «более стандартными» способами делать вещи на других языках. (или C99 ...)


2

Нет.

Единственная причина, по которой программист C должен знать о существовании alloca, - это понимать и исправлять унаследованный код, который его использует.

Любое использование allocaлибо

  1. Бесполезно, т. Е. Тривиально может быть заменено переменными фиксированного размера автоматической продолжительности хранения, ИЛИ
  2. Опасное переполнение стека, ожидающее произойти.

Помимо нескольких мысленных экспериментов, для которых я никогда не находил реальных примеров, не существует ни allocaодного варианта использования (или VLA), который не был бы ни бесполезным, ни уязвимым (один из двух вышеупомянутых случаев).


2
Конечно, абсолютно никто никогда не мог использовать это ответственно. Нет никогда.
DeadMG

Единственное «ответственное» использование на alloc100% эквивалентно автоматическим массивам фиксированного размера и менее переносимо.
R .. GitHub ОСТАНОВИТЬ ЛЬДА

Я полагаю, что никто никогда не захочет выделить какое-то динамическое количество, скажем, несколько килобайт, которые никогда не переполнятся. Или вызовите некоторую функцию API OS, которая скажет им, сколько доступно. Или просто увеличьте размер стека.
DeadMG

Если это несколько КБ, и вы уверены, что у вас есть несколько КБ, вы можете просто использовать T foo[5000];или что-то еще.
R .. GitHub ОСТАНОВИТЬСЯ, ПОМОГАЯ ЛЬДОМ

Только если T имеет тривиальный конструктор по умолчанию. Если бы я нуждался в производительности, даже простое обнуление памяти могло бы стоить мне. Но другие типы могут иметь еще более сложную логику построения по умолчанию. Если бы я хотел, например, динамически создать массив std::mutex, я мог бы вызвать вызов ядра и переключение контекста для пяти тысяч мьютексов. Не дешево. Не говоря уже о дополнительной стоимости кэша размещения локальных переменных после массива.
DeadMG

1

Мое мнение таково: не поощряйте его использование, если вы не обучаете принципам низкоуровневого компилятора, используемым для выделения стекового пространства для локальных переменных. Научите этому в этом контексте.


0

В документации GCC есть пара практических плюсов и минусов alloca(). С практической точки зрения, приличное количество свободного программного обеспечения использует его, поэтому хорошо понимать, как оно работает и где оно используется в существующем коде.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.