Используйте alloca()
(иногда называемый _alloca()
или _malloca()
), но будьте очень осторожны с этим - он освобождает память, когда выоставляйте функцию, а не выходя из области видимости, поэтому вы быстро взорветесь, если будете использовать ее внутри цикла.
Например, если у вас есть такая функция, как
int foo( int nDataSize, int iterations )
{
for ( int i = 0; i < iterations ; ++i )
{
char *bytes = alloca( nDataSize );
// the memory above IS NOT FREED when we pass the brace below!
}
return 0;
} // alloca() memory only gets freed here
Затем alloca () будет выделять дополнительные nDataSize байтов каждый раз через цикл .Ни один из байтов alloca () не освобождается, пока вы не вернетесь из функции.Итак, если у вас nDataSize
1024 и iterations
8, вы выделите 8 килобайт перед возвратом.Если у вас есть nDataSize
= 65536 и iterations
= 32768, вы выделите в общей сложности 65536 × 32768 = 2 147 483 648 байт, почти наверняка взорвав свой стек и вызвав сбой.
anecdote: Вы можете легко попасть в неприятности, если будете писать после конца буфера, особенно если вы передаете буфер в другую функцию, и эта подфункция имеет неверное представление о длине буфера. Однажды я исправил довольно забавную ошибку , когда мы использовали alloca()
для создания временного хранилища для рендеринга глифа шрифта TrueType перед отправкой его в память графического процессора.Наша библиотека шрифтов не учитывала диакритический знак в шведском символе Å при расчете размеров глифов, поэтому она предложила нам выделить n байтов для хранения глифа перед рендерингом, а затем фактически отрисовать n + 128 байт.Дополнительные 128 байтов записываются в стек вызовов, перезаписывая адрес возврата и вызывая действительно болезненный недетерминированный сбой!