0

Does this code return an invalid reference to a variable allocated on the stack? Or what:

void *f(size_t sz) {
    return alloca(sz);
}

Or is it a special case that is handled by the alloca implementation / compiler support like f(alloca(size), alloca(size)) would be?

Hossein
  • 4,097
  • 2
  • 24
  • 46
user318904
  • 2,968
  • 4
  • 28
  • 37
  • 1
    Slightly aside from your question, but `alloca` may always return an invalid pointer and there's really nothing you can do about it. Code using `alloca` is almost certainly wrong code, and likely subject to serious vulnerabilities. – R.. GitHub STOP HELPING ICE Aug 13 '11 at 12:59
  • To R.: this "Code using alloca is almost certainly wrong code" is a statement similar to "any use of knife is wrong" or some such. alloca is powerful feature when used responsively and with purpose. – c-smile Sep 02 '11 at 06:13

6 Answers6

5

alloca allocates space in the stack frame of f. You can't do anything useful with it once the function returns (it's not "reserved" anymore).

The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
2

this:

void *f() {
    char* pc4 = alloca(4);
    ...
}

is exactly this:

void *f() {
    char pc4[4];
    ...
}

Neither you can return / use pc4 outside the function in second case nor you can do the same in first case.

c-smile
  • 26,734
  • 7
  • 59
  • 86
1

As per the Linux manual page:

The alloca() function allocates space in the stack frame of the caller, and returns a pointer to the allocated block. This temporary space is automatically freed when the function from which alloca() is called returns.

That means, an attempt to access the memory returned by f() will lead to undefined behavior as it is freed when f() returns.

Azzabi Haythem
  • 2,318
  • 7
  • 26
  • 32
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93
1

Yes, the code returns an invalid pointer. alloca call cannot be wrapped into a function. If you need to wrap alloca, you are limited to macro wrappers.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

As others have said, it'll be freed, and I don't really see how you could change the behavior. If you look at how an alloca compiles on amd-64:

pushq   %rbp
movq    %rsp, %rbp
subq    $144, %rsp
movq    %rsp, %rax
addq    $15, %rax
shrq    $4, %rax
salq    $4, %rax
leave
ret

You see

1) Alloca isn't actually a function call (because, as you said, it would have to handle the stack differently!)

2) Whatever alloca does to the stack pointer is just going to get clobbered at the end of the function when rbp overwrites rsp

So could you get the behavior you ask about (without writing assembly)? That's a tricky question, and I don't know, but it seems like probably not.

Owen
  • 38,836
  • 14
  • 95
  • 125
0

I have never used alloca myself but I read about "inline problem" here: Why is the use of alloca() not considered good practice?

The answer "One of the most memorable bugs ..." is very interesting.

So it is not true that the memory will definitely be freed when the function goes out of scope.

Community
  • 1
  • 1
Daniel Marjamäki
  • 2,907
  • 15
  • 16