LINUX.ORG.RU

Большие объекты на стеке

 ,


0

4

Как вы относитесь к сабжу? Например, нужно выделить локальный буфер размером больше одной страницы, порядка 16-64Кб, в многопоточной программе, так что статические буферы отпадают. Дергать malloc неудобно, нужно потом освобождать память во многих местах, локальный буфер на стеке намного удобнее. С другой стороны есть риск, что обращение к стеку перескочит через т.н. guard page и вызовет сегфолт. Или стек внезапно закончится. Тогда получается, что обработать ошибку выделения памяти malloc()-ом проще. Как предпочитаешь ты, $username?

★★★★★
Ответ на: комментарий от anonymous

Зависит от алгоритма, если в одном потоке, запустить такую функцию рекурсивно, стек может и кончиться (где то на 34 итерации):)

batbko
()
Ответ на: комментарий от batbko

Зависит от алгоритма, если в одном потоке, запустить такую функцию рекурсивно, стек может и кончиться (где то на 34 итерации):)

Размер стека это не фиксированная величина и может быть изменена при компиляции.

Norgat ★★★★★
()

Буфер можно сделать статическим локальным для потока (TLS). А вообще зависит от количества потоков и размера стека

vromanov ★★★
()
Ответ на: комментарий от batbko

ТС беспокоит не рекурсивные алгоритмы, а возможность выделить на стеке потока 64 Кб. Это возможно?

anonymous
()

Да аллоцируй в куче, если боишься

shamaz
()

порядка 16-64Кб

дефолтный размер стека 8-10Мб, так что эти Кб погоды не сделают

обработать ошибку выделения памяти malloc()-ом проще

с большой вероятностью к тебе раньше придет белочка OOM-killer

wota ★★
()

Дергать malloc неудобно, нужно потом освобождать память во многих местах

Делаешь единственную точку выхода из функции, там и освобождаешь, вместо раннего выхода из функции - goto в нужную точку перед return.

А вообще надо использовать классы, которые реализуют управление ресурсами, RAII во все поля и перестать беспокоиться о множественных точках освобождения ресурсов.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

А вообще надо использовать классы, которые реализуют управление ресурсами, RAII во все поля и перестать беспокоиться о множественных точках освобождения ресурсов.

Не везет вам, плюсовикам

shamaz
()

небольшое уточнение, буфер нужен в библиотеке, которой желательно быть максимально портабельной

Я нагуглил про всякие -fstack-check у GCC и аналогичную опцию у cl.exe, но существуют ещё другие компиляторы, с какими опциями будут скомпилированы вызывающие библиотеку приложения и сколько у них уже будет отожрано стека на момент вызова заранее неизвестно. Поэтому интересуюсь best practices, так сказать :)

Harald ★★★★★
() автор топика

А я не парюсь и всегда malloc использую. Даже модные "динамические" массивы на стеке не использую, т.к. знаю, что эта хрень в любой момент может выдать неожиданную жопу. Конечно, подчистка хвостов — дело тяжелое. Но что ж поделать, коли ИИ в gcc еще не внедрили (и слава Чайнику Рассела, иначе бы тупой "шалом, мир" отжирал бы с сотню мегабайт памяти).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Norgat

Но, по умолчанию 2mb, под виндой вроде 20, или тоже 2.

batbko
()
Ответ на: комментарий от anonymous

Ну ТС, то так то мог бы и погуглить про дефолтный размер, сабжа под сабжем:)
А я указал, какие бывают грабли.
Дабы анон не бушевал, таки да - 64 кб, можно безопасно выделить на стеке.
До тех пор, пока это 64 кб на поток, и до тех пор пока уверен что так делает только твой код...

batbko
()
Ответ на: комментарий от Harald

В ядре не стоит, там, емнип, до сих пор стек ограничен в районе 8 КБ. В userspace - порядка 8 МБ лимит. Если реально ускоряет работу и нет вероятности рекурсии - выделяй свои 64 КБ на стеке.

Как-то обнаружил stack overflow при 5-кратной вложенности макросценария в Asterisk Dialplan. Неприятная штука. До сих пор обескураживает, что контроллировать переполнение стека невозможно. Поэтому во имя безопасности лучше не баловаться. С ужасом смотрю на stack trace-ы GStreamer, видал по 70 фреймов.

Krieger_Od ★★
()

не парюсь и использую alloca. К ужасу многих спокойно отношусь к goto и setjump, setcontext. Если есть средство, отчего же его не использовать?

ps. молотком принято забивать гвозди (в некоторых странах и шурупы), а возможность отбить пальцы не повод избегать молотков

MKuznetsov ★★★★★
()
Ответ на: комментарий от Begemoth

И каким боком оно к gcc относится? Или ты хочешь мне предложить вместо вкусного С использовать проплесневевший С++?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от MKuznetsov

К ужасу многих спокойно отношусь к goto и setjump, setcontext

А чего там ужасаться-то? Все равно компилятор циклы и прочее превратит в goto…

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Krieger_Od

я сейчас поэкспериментировал, на линуксе к любому участку дефолтных 8Мб стека можно обращаться сразу и не падает, в винде скомпилированный mingw код перед вычитанием из регистра esp вызывает _chkstk_ms и я не нашёл как это отключить, -fno-stack-check не помогает, пожалуй можно забить и не париться :)

Harald ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

И каким боком оно к gcc относится

Таким, что gcc - это compiler collection.

окаменевшего С, использовать С++?

1. Пофикшено. 2. Да :-) и твой код станет проще.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Не, это если тупо вместо printf зафигачить cout ☺

А вообще, да, я согласен: иногда могут возникнуть задачи, требующие ООП. Но у меня таких задач вообще нет. И не будет, т.к. я — прикладник, гуевины мне не нужны; а четкой структуры объектов в моих задачах нет.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от eagleivg

и на Commodore 64 тоже столько лучше не выделять на стеке. Да.

anonymous
()
Ответ на: комментарий от Eddy_Em

Я тебе привёл пример как С++ может тебе помочь - управление ресурсами, причём для управления памятью уже в стандартной библиотеке С++: std::vector вместо ручного выделения/освобождения памяти под массивы, std::shared_ptr, std::unqiue_ptr для одиночных объектов на куче. ООП там нет никакого, вообще почти вся стандартная библиотека С++ - не объектно-ориентированная.

Begemoth ★★★★★
()

А нельзя объект на куче, а ссылки на него на стеке с ref counter?

vertexua ★★★★★
()

Например, нужно выделить локальный буфер размером больше одной страницы, порядка 16-64Кб, в многопоточной программе, так что статические буферы отпадают

void
func(void *param)
{
    static __thread char buf[65536];

    ...
}
i-rinat ★★★★★
()

64 килобайта. Может задачу по другому поставить или посмотреть на нее с другой стороны? и окажется, что не особо то и нужен такой объем, особенно на стеке.

anonymous
()

Короткий ответ: попробуй посмотреть, какой год сгенерирует компилятор для

void func()
{
  char buf[много_много];
  /* тут какой-то код, использующий buf */
}

Более длинный ответ: когда я интересовался этим в последний раз (тогда еще сложилась ситуация, что gcc считался отстоем и все переходили на egcc), mingw gcc создавал вызов malloc для таких объектов, ну а в тех местах, где стоял return добавлял free.

x_hash
()
Ответ на: комментарий от Begemoth

С ним бесполезно спорить, он привык танцевать гопак на си вместо того чтобы сосредоточиться на задаче и считает, что это единственно верный путь :)

Reset ★★★★★
()
Ответ на: комментарий от Reset

Кути как были говном, так говном и остались. И маловероятно, что не перестанут быть говном. GTK, кстати, не лучше.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Reset

И что с того, что оно кроссплатформенное? Говно — оно и в Африке говно, как ты его розами не посыпай!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

А что в кругах не программистов сейчас считается не говном для написания GUI?

Я не программист :) Для мелочи - тикль, для всех - веб, для офтопиков - натив, для линукса гуй не нужен :)ь

yyk ★★★★★
()
Ответ на: комментарий от Eddy_Em

Не, это если тупо вместо printf зафигачить cout ☺

Так юзай printf в плюсах, кто запрещает то... я вообще прикрутил свой printf через шаблоны с переменным числом аргументов - вместо процента втыкает аргумент, тип оно знает само. Еще макрос у меня есть волшебный для отладки, пишешь например

WOUT(a, a+b, a+b*c) 
и получаешь значения выражений в таком примерно виде
file line: a=..., a+b=..., a+b*c=...
В сишечке такое скорей всего не сделать.

иногда могут возникнуть задачи, требующие ООП. Но у меня таких задач вообще нет. И не будет, т.к. я — прикладник, гуевины мне не нужны;

Таки я тоже;-) У нас весь гуй ваяется на Tkintere, а С++ и ООП юзается во все поля. Скажем последний проект (наверное я ничего сложнее в жизни не делал) - предыдущая версия от коллег на фортране больше 11 тысяч строк, у меня сейчас на плюсах примерно тысяча, при этом у меня гораздо более сложные/продвинутые алгоритмы используются.

четкой структуры объектов в моих задачах нет.

То, что ты ее не видишь, не значит что ее там нет. Это характеризует твой уровень, а не твои задачи.

Ты не прав в своем отношении к плюсам, тебе много раз об этом разные люди говорили. Печалит то, что ты не хочешь развиваться, и продолжаешь считать что быдлокодинг в наукоемком софте - это хорошо... Разберись уже с плюсами, ничего там нету сложного - производительность труда вырастет весьма существенно.

AIv ★★★★★
()
Ответ на: комментарий от Eddy_Em

Но что ж поделать, коли ИИ в gcc еще не внедрили (и слава Чайнику Рассела, иначе бы тупой «шалом, мир» отжирал бы с сотню мегабайт памяти).

Необязательно. ИИ может работать на этапе компиляции. См rust, например, с его контролем указателей.

anonymous
()
Ответ на: комментарий от AIv

Разберись уже с плюсами, ничего там нету сложного - производительность труда вырастет весьма существенно.

Мне это не нужно.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Ты не знаешь нужно это тебе или не нужно, потому что ты не понимаешь о чем идет речь. Все равно, что мальчику который решает СЛАУ предложили бы таки научится обращать матрицы, а он бы сказал «мне это ненужно» и продолжал пытаться подбирать ответ методом тыка...

AIv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.