Вот опасный, но быстрый и маленький ответ:
template<class T>
struct alloca_magic {
T* b;
int s;
alloca_magic(void* bu, int sz)
: b((T*)(bu)),s(sz)
{new(b)T[s];}
~alloca_magic()
{for(int i=0;i<s;++i)(b+i)->~T();}
operator T*() {return b;}
};
#define alloca_magic(Type,Name,Size) void* t = alloca(sizeof(Type)*Size); alloca_magic<Type> Name(t,Size);
#include <iostream>
struct test {
int data;
test() {std::cout << "ctor\n";}
~test() {std::cout << "dtor\n";}
};
void foo(int len) {
std::cout << "begin foo\n";
alloca_magic(test ,buffer,len);
for(int i=0; i<len; i++)
buffer[i].data = i;
std::cout << "end foo\n";
}
int main() {
int len;
std::cin >> len;
std::cout << "begin main\n";
alloca_magic(test ,buffer,len);
for(int i=0; i<len; i++)
buffer[i].data = i;
foo(len);
std::cout << "end main\n";
}
http://ideone.com/ccvTR Результаты:
begin main
ctor
ctor
ctor
begin foo
ctor
ctor
ctor
end foo
dtor
dtor
dtor
end main
dtor
dtor
dtor
Для окон вам придется заменить alloca
на _alloca
. Имейте в виду, что этим легко злоупотреблять и нарушать, и если оно сделано с большими числами, это может вызвать переполнение стека. Я не рекомендую это для чего-либо, кроме скоростных тестов, и, вероятно, тоже нет.