Question

If the alloca() function gets called multiple times in a particular function is it guaranteed that all the stack segments allocated by it form a contiguous part of stack memory altogether?

Was it helpful?

Solution 2

is it guaranteed that all the stack segments allocated by it form a contiguous part of stack memory altogether?

No. If it were guaranteed, you could read all about it in it's documentation. alloca is an implementation defined function (the only one who could tell you what guarantees you have on it is your compiler's implementer).

It is also non-standard, unsafe, and non-portable (basically worse than using malloc and free in C++).

Unless you want to know how legacy code (using it) behaves, the only think you get by using it, is lower code quality.

OTHER TIPS

Maybe. There is no alloca in C, C++ or Posix. It is a frequent extension in Unix based systems, but each system defines it like it wants. (The documentation of the GNU version suggests that they would be contiguous, but I see no actual guarantee.)

As said by others the short answer is 'no'.

However reading implementer docs or even reverse engineering could allow you to make such assumptions (or not).

I ran this example at cpp.sh which says void* is size 8 and diff is (-32):

// Example program
#include <iostream>
#include <string>
#include <alloca.h>
#include <stdint.h>

int main()
{
  void *var1 = alloca(sizeof var1);
  std::cout << "sizeof var1: " << sizeof var1 << std::endl;
  std::cout << "var1 addr: " << var1 << std::endl;
  void *var2 = alloca(sizeof var2);
  std::cout << "var2 addr: " << var2 << std::endl;
  intptr_t diff = (intptr_t)var2 - (intptr_t)var1;  
  std::cout << "addr diff: " << diff << std::endl;
}

Huh. Not contiguous. Maybe there is some simple padding going on.

Making allocation of size 128 byte gives a diff of (-144):

// Example program
#include <iostream>
#include <string>
#include <alloca.h>
#include <stdint.h>

int main()
{
  int size = 128;
  void *var1 = alloca(size);
  std::cout << "var1 addr: " << var1 << std::endl;
  void *var2 = alloca(size);
  std::cout << "var2 addr: " << var2 << std::endl;
  intptr_t diff = (intptr_t)var2 - (intptr_t)var1;  
  std::cout << "addr diff: " << diff << std::endl;
}

Hm. Alignment is not restricted to 32-byte...

Further reverse engineering left as student excercise.

(From just two tests I have a pretty good guess of what is going on without any documentation. Making a few more should narrow it down quite a bit.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top