Динамически выделяемая память стека с областью действия класса

Некоторые компиляторы поддерживают расширения C++, позволяющие динамически выделять память в стеке. Например, g++ поддерживает alloca(), а также VLA. Все эти расширения поставляются с оговоркой, что динамически выделяемая память «освобождается» в конце области действия вызывающей функции. (Редактировать: чтобы уточнить, я использую кавычки вокруг «освобожденного», потому что на самом деле происходит то, что компилятор уменьшает/увеличивает указатель стека, поэтому alloca() требует поддержки компилятора.) Это означает, что память, выделенная с использованием alloca() в конструкторе класса освобождается, как только конструктор возвращается.

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

Можете ли вы придумать какой-нибудь способ обойти это ограничение, чтобы я мог использовать alloca(), VLA или какое-либо другое языковое расширение, чтобы память могла быть выделена внутри класса и иметь область класса?


person void-pointer    schedule 31.07.2012    source источник
comment
Есть ли причина, по которой вы должны использовать стек для выделения вместо кучи?   -  person TheSteve    schedule 31.07.2012
comment
@void-pointer захватывает часть памяти из кучи и использует ее как собственный эффективный стек.   -  person R. Martinho Fernandes    schedule 31.07.2012
comment
@void-pointer: вы можете быть удивлены тем, насколько быстро работает куча. Некоторые обходные пути заключаются в том, чтобы (1) иметь статическую функцию, которая вычисляет, сколько места должно быть зарезервировано вызывающей функцией, и (2) использовать конструктор макросов. Но на самом деле просто используйте кучу.   -  person Mooing Duck    schedule 31.07.2012
comment
Причина, по которой я действительно хотел это сделать, состоит в том, чтобы точно определить, как распределение кучи сравнивается с alloca() в моем приложении.   -  person void-pointer    schedule 31.07.2012
comment
@void-pointer: в этом случае также проверьте собственный распределитель стека.   -  person Mooing Duck    schedule 31.07.2012


Ответы (1)


Нет, это невозможно. Класс не может выделять локальную память для функций — это просто не имеет смысла.

Однако вы можете добиться очень быстрого выделения кучи с помощью соответствующего специального распределителя, такого как арена памяти, до такой степени, что это будет более чем достаточно быстро. Что вам нужно помнить, так это то, что new — это ядерная боеголовка выделения памяти — она должна поддерживать любой размер выделения и любой шаблон выделения/освобождения. Что-то более конкретное может работать намного быстрее - до такой степени, что оно вполне конкурентоспособно с памятью, выделенной стеком. В Visual Studio 2010 я даже смог заставить его выполняться быстрее, чем alloca.

person Puppy    schedule 31.07.2012
comment
Хм, это действительно интересно. Думаю, мне нужно провести сравнительный анализ. - person void-pointer; 31.07.2012