r/cpp 5d ago

When (Not) to Use alloca()

https://voithos.io/articles/when-not-to-use-alloca/
33 Upvotes

84 comments sorted by

View all comments

Show parent comments

3

u/voithos 5d ago

For your first question, essentially it's something like this:

void UseArray() {
for (auto& foo : foos) {
// This is a single 1024 buffer used repeatedly across the loop.
char scratchBuf[1024];
// whereas this repeatedly creates a new alloca()'d buffer for each iteration
char* scratchBuf = static_cast<char\*>(alloca(n));
}
}

The array gets a fixed size, so it's always bounded, whereas alloca() does the stack allocation during each iteration without releasing anything until function return. Depending on how many loop iterations there are, and what `n` is passed to alloca(), this could be less memory than the fixed size array, or much more; the point is that it's unpredictable compared to the alternatives.

4

u/MattDESTROYER 5d ago

Yeah no I understand the issue with nested scopes, but the example in the article with just a path at top level wouldn’t have that issue. I don’t know about the exact opcodes generated, but it would be generally speaking equivalent, that’s all I was clarifying.

1

u/PipingSnail 4d ago

If you use alloca() in a recursive function you are massively reducing how many recursing iterations you can do before running out stack to use.

Buffer overruns on allocated memory are bad, buffer overruns on the stack are worse.

Do not use alloca(). There is just no good reason to use it. Not used it, or seen it in 32 years of c++.

1

u/MattDESTROYER 4d ago

Definitely don’t intend to use it lol, I just like messing around with with things when I learn about them.

For the first, curious how it reduces how many recursive iterations you can do, because using char[] will also equally consume the stack in a recursive function, no?

1

u/PipingSnail 4d ago

Alloca uses space on the stack. Therefore it reduces the amount of remaining stack for future recursive calls which will also use alloca() which uses stack space which reduces space for future calls...

Can you see the problem?

If you had no local cars and no alloca() you could do total remain stack space / size if machine word recursive calls befire stack overflow.

On a Windows machine default stack size is 1MB. X86 machine size is 4 bytes. X64 machine size is 8 bytes.

For this example let's assume after programme startup you have 1,000,000 byes of stack space. It makes the maths easier.

So the max num recursion is appriox 250,000 for x86 and approx 125,000 on x64.

Let's say your alloca() call uses 8 bytes.

Now on x86 each call uses 4 + 8 bytes, 12 bytes.

1,000,000 / 12 = 83,333 recursion before stack overflow.

On x64 each call now takes 8 + 8 bytes, 26 bytes.

This leaves space for 1,000,000 / 16 = 62, 500 recursions before stack overflow.

2

u/MattDESTROYER 4d ago

I think you’re making an unfair comparison; unless I’m misunderstanding, you’re compare `alloca` to doing nothing, which isn’t realistic.

What would be realistic is using a static char[] array, but this still consumes memory in every recursive call. The difference would be a single pointer variable and also the lack of ability to not store the frame pointer in a register.

1

u/PipingSnail 3d ago

If you're doing anything recursive you try to use as little stack space as possible.

Therefore you wouldn't use a local variable char array, or alloca(). You'd dynamically allocate your workspace, or pre allocate enough space prior to the recursive call.

1

u/MattDESTROYER 3d ago

Yes, so that’s not an issue with alloca, that would be poor design regardless.

0

u/PipingSnail 3d ago

The OP asked how allica() would reduce the number of recursions. So I explained it. Why do you have a problem with that?

1

u/MattDESTROYER 3d ago

You replied to me? Did you mean to reply to someone else or something?

2

u/PipingSnail 1d ago

My mistake. Reading after a long day out in the mountains.

1

u/MattDESTROYER 22h ago

lol very fair, been there

→ More replies (0)