9

What is the difference between

void *bytes = alloca(size);

and

char bytes[size];  //Or to be more precise, char x[size]; void *bytes = x;

...where size is a variable whose value is unknown at compile-time.

Shog9
  • 156,901
  • 35
  • 231
  • 235
Jared Pochtar
  • 4,925
  • 2
  • 29
  • 39
  • 1
    The answer depends critically on whether `size` a compile-time constant. Is it? – AnT stands with Russia Apr 10 '10 at 19:10
  • no, size is, for all intents and purposes, an argument to the function – Jared Pochtar Apr 10 '10 at 19:19
  • That doesn't matter. Apple, by default, uses `--std=gnu99` which supports both. `alloca()` is a GNU extension, and the variable length array is a standards-compliant C99 feature. – mbauman Apr 12 '10 at 17:19
  • @Matt B.:What does Apple have to do with any of this? – Billy ONeal Apr 20 '10 at 14:19
  • 2
    @Billy: The question is tagged `objective-c`. I know that Mac development is not the only use of Obj-C, but that's the most likely application of the language. My point was that `size` need not be constant with C99/gnu99, and that it is a default mode in Xcode. A minor (slightly unrelated) correction to my previous comment would be s/Apple/Xcode/. – mbauman Apr 20 '10 at 14:29

6 Answers6

17

alloca() does not reclaim memory until the current function ends, while the variable length array reclaims the memory when the current block ends.

Put another way:

void foo()
{
    size_t size = 42;
    if (size) {
        void *bytes1 = alloca(size);
        char bytes2[size];
    } // bytes2 is deallocated here
}; //bytes1 is deallocated here

alloca() can be supported (in a fashion) on any C89 compiler, while the variable length array requires a C99 compiler.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 2
    @Billy: the memory allocated by char bytes[size] is not guaranteed to be physically reclaimed at the end of current block; however the access after the current block is not possible anymore. – Vlad Apr 10 '10 at 19:08
  • 2
    @Vlad: Technically the C standard mentions very little about where things actually need to be physically stored to avoid any possible dependency on a particular architecture. However, even if something is not in the standard explicitly, the implicit meaning in the standard results in 99.9% of compilers implementing it that way. – Billy ONeal Apr 10 '10 at 19:15
  • Good Answer Billy :). Liked it. – Priyanka Mishra Apr 12 '10 at 10:27
6

From the GNU documentation:

Space allocated with alloca exists until the containing function returns. The space for a variable-length array is deallocated as soon as the array name's scope ends. (If you use both variable-length arrays and alloca in the same function, deallocation of a variable-length array will also deallocate anything more recently allocated with alloca.)

Additionally, alloca is not a standard C function, so support is not guaranteed across all compilers. Variable length arrays are part of the C99 standard, so any C99-supporting compiler should implement it.

rjh
  • 49,276
  • 4
  • 56
  • 63
5

Besides the point Billy mentioned, alloca is non-standard (it's not even in C99).

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

In the second form, size must be a constant known to compile time.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • Possibly, but it's more likely the OP is referring to variable length arrays, part of the C99 standard. – rjh Apr 10 '10 at 19:08
0

Besides the already-discussed points of when exactly the space is freed, and whether the construct is supported at all, there is also this:

  • In the alloca case, bytes has a pointer type.
  • In the [] case, bytes has an array type.

The most noticeable difference is in what sizeof(bytes) is; for a pointer it is the size of the pointer (sizeof(void *)) whereas for an array it is the size of the allocated space (sizeof(char) * size, which = size for this case since sizeof(char) = 1).

(Also, in your example, the element types are different; to be the same, the first should be changed to char *bytes = alloca(size).)

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
0

The biggest difference is that alloca does not call constructors or destructors when you are using the memory as class variables.

The other differences are less likely to be noticed, but can become apparent in some weird run time errors in some situations.

nategoose
  • 12,054
  • 27
  • 42