#include <iostream>
#include <malloc.h>
void print_vals(int n)
{
int *arr = (int *)alloca(n);
for (int i = 0; i < n; i++)
arr[i] = i;
for (int i = 0; i < n; i++)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
int main()
{
print_vals(5);
print_vals(10);
}
When I run this code, I get this error per call:
Run-Time Check Failure #4 - Stack area around _alloca memory reserved by this function is corrupted
I'm using Visual C++ 2019, both stdc++14 and stdc++17 produce the same error.
What's wrong with this code?
I'm going to assume this is just sample code since, if your intent is just to print the numbers
0..n
, there's absolutely no reason why you would use an array for this :-)On to your actual problem, the
alloca
function, likemalloc
, allocates a number of bytes. If you then treat it as if you have a number ofint
values (which are almost certainly larger than a byte), that won't end well. That's actually confirmed in the dialog box you see where the size is ten but each array element takes up four:What you would need to do is something like:
In any case, I would be avoiding
alloca
because:new
would.On that last point, the Linux doco for
alloca
states (my emphasis):If you want something where you don't have to worry about de-allocating it yourself, modern C++ has smart pointers, so you could use something like:
When that
arr
variable goes out of scope, the memory that was allocated for it will be automagically released. You can try that in this complete variation on your original code:As an aside, you'll notice I've also changed to using
size_t
rather thanint
for the size and indexes - I believe that's a better fit. Now, granted, this uses the heap rather than the stack, but it's the safer way to do it, based on the earlier comments aboutalloca
.You could make
alloca
a little more likely to succeed if you guaranteed some limit on the size, such as with:But that doesn't actually guarantee its safety and, if you're going to do that, you may as well use a fixed buffer anyway since you'll know the maximum size:
One other solution I'd like to put forward: if your intent is to be as efficient as possible, you could use a hybrid approach. By that, I mean using a local buffer for below a certain size and allocating memory only if needed: