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

Годы и несколько лет назад, у меня было приложение, которые отправляют двоичные данные - оно сделало каждый отправляет с размером следующего буфера, и затем другой отправляет с буфером (несколько сотен байтов). И после профилирования, мы обнаружили, что могли получить главное ускорение путем превращения их в один буфер и отправки его только однажды. Мы были удивлены - даже при том, что существует некоторая сеть наверху на каждом пакете, мы не думали, что это было значимым фактором.

6
задан Community 23 May 2017 в 12:11
поделиться

5 ответов

Я не уверен, что вам нужно.

Если вам нужны только типичные числа, то попробуйте! Создайте функцию с вложенными областями видимости, каждая из которых выделяет дополнительное пространство стека. Выход в каждой области. Посмотрите, как далеко зайдет эта штука.

Если вам нужны конкретные числа в конкретной ситуации, спросите себя, что бы вы хотели делать, когда они у вас есть? Разветвляться на разные реализации? Это похоже на проблему технического обслуживания, использование которой должно быть очень хорошо оправдано. Что вы ожидаете получить? Неужели это стоит таких хлопот?

Я согласен, что 10k обычно не должно быть проблемой. Так что, если ваш код не критичен, используйте boost :: array (или std :: tr1 :: array , если с ним идет ваша std lib). В противном случае просто используйте std :: vector или, если вы чувствуете, что должны, boost :: scoped_array (или std :: tr1 :: scoped_array , если ваша std lib идет с ним).

0
ответ дан 9 December 2019 в 22:37
поделиться

В Windows размер стека по умолчанию составляет 1 МБ, поэтому вероятность переполнения стека с массивом всего 10 КБ маловероятна. Тем не менее, я считаю, что выделение такого большого объема памяти в стеке - плохая практика, и вам следует попытаться выделить его динамически, если можете. Существует также массив Scoped Array , который хорошо определен для автоматического управления массивами - в отличие от класса vector , его нельзя копировать.

3
ответ дан 9 December 2019 в 22:37
поделиться

"std :: auto_ptr, который используется для управлять выделенным в куче char [] ... это неопределенное поведение согласно C ++ "

Это неверное предположение! STL auto_ptr имеет точное описание поведения. Если вы беспокоитесь о потере контроля во время сложного обзора присваивания, можно использовать шаблон счетчика ссылок для управления разрушением массива, выделенного кучей.

-2
ответ дан 9 December 2019 в 22:37
поделиться

I second 1800 ИНФОРМАЦИЯ:

  • По возможности разместите свои данные в куче. Это безопаснее (например, труднее использовать переполнение буфера) и более гибким, когда (не если) вам нужно будет расширить дизайн позже.

  • Используйте std :: vector, boost :: scoped_array или boost :: shared_array.

I знаю, что он не отвечает на ваш вопрос об определении размера стека, но я думаю, что это логичный ответ на вашу проблему.

1
ответ дан 9 December 2019 в 22:37
поделиться

Я не знаю ни одного способа определить размер стека напрямую с помощью API, если у вас нет доступа к вызову CreateThread или, если это основной поток, глядя на размер потока EXE по умолчанию в заголовке PE.

В вашей ситуации я бы выделил в куче, чтобы быть безопасным, даже если массив небольших данных 10 КБ вряд ли достигнет максимума стека в не- рекурсивные сценарии.

Однако вы можете проверить предел стека, если все будет сделано осторожно. Стек фиксируется в страницах по 4 КБ, когда вы касаетесь их (через защитные страницы ), пока не достигнете предела, после чего Windows выдаст исключение переполнения стека. На момент отправки исключения остается одна страница стека, чтобы могла выполняться сама логика диспетчеризации исключений (включая функции фильтрации), но Windows выдает исключение , потому что не может выделить другую страницу защиты . Это означает, что следующее переполнение стека или проверка приведет не к исключению переполнения стека, а к нарушению доступа . Таким образом, чтобы зондирование работало надежно (и, в частности, повторялось), вам необходимо декомпозировать память, выделенную зондированием, и восстановить защитную страницу.

В этой статье в KB описывается, как декомпозировать стековую память и восстановить защитную страницу. Он проверяет, используя рекурсию и приращение 10 000 байт; компилятор по умолчанию реализует собственное зондирование стека для выделения локальных элементов в стеке> 4 КБ, так что механизм роста стека работает правильно.

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

В этой статье в KB описывается, как декомпозировать стековую память и восстановить защитную страницу. Он проверяет, используя рекурсию и приращение 10 000 байт; компилятор по умолчанию реализует собственное зондирование стека для выделения локальных элементов в стеке> 4 КБ, так что механизм роста стека работает правильно.

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

В этой статье в KB описывается, как декомпозировать стековую память и восстановить защитную страницу. Он проверяет, используя рекурсию и приращение 10 000 байт; компилятор по умолчанию реализует собственное зондирование стека для выделения локальных элементов в стеке> 4 КБ, так что механизм увеличения стека работает правильно.

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

В этой статье в KB описывается, как декомпозировать стековую память и восстановить защитную страницу. Он проверяет, используя рекурсию и приращение 10 000 байт; компилятор по умолчанию реализует собственное зондирование стека для выделения локальных элементов в стеке> 4 КБ, так что механизм увеличения стека работает правильно.

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

В этой статье в KB описывается, как декомпозировать стековую память и восстановить защитную страницу. Он проверяет, используя рекурсию и приращение 10 000 байт; компилятор по умолчанию реализует собственное зондирование стека для выделения локальных элементов в стеке> 4 КБ, так что механизм увеличения стека работает правильно.

9
ответ дан 9 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: