55

Is there a way to allocate memory on stack instead of heap? I can't find a good book on this, anyone here got an idea?

17
  • If you want to control where a std::string or std::vector allocates its memory, check this question: stackoverflow.com/questions/354442/…
    – Zan Lynx
    Commented Jun 13, 2011 at 19:14
  • 1
    @Neil: to quickly allocate/free temporary working space? Commented Jun 13, 2011 at 19:15
  • 2
    @Neil: and if the function needs a small, yet variable, number of temporary objects? You could use a vector, but if that function is invoked in a tight loop, it'd be cool if the memory can be quickly allocated and freed without worrying about fragmentation. Commented Jun 13, 2011 at 19:18
  • 1
    @Andre - Then allocate a small, yet fixed, number of objects on the stack. If we don't know the upper bound, alloca will blow anyway.
    – Bo Persson
    Commented Jun 13, 2011 at 19:22
  • 1
    @Alf I've been programming for Windows since 2.0 and have never used it, or seen it used.,
    – user2100815
    Commented Jun 13, 2011 at 19:50

7 Answers 7

63

Use alloca() (sometimes called _alloca() or _malloca() ), but be very careful about it — it frees its memory when you leave a function, not when you go out of scope, so you'll quickly blow up if you use it inside a loop.

For example, if you have a function like

int foo( int nDataSize, int iterations ) 
{
   for ( int i = 0; i < iterations ; ++i )
   {
      char *bytes = alloca( nDataSize );
      // the memory above IS NOT FREED when we pass the brace below!
   } 
   return 0;
}  // alloca() memory only gets freed here

Then the alloca() will allocate an additional nDataSize bytes every time through the loop. None of the alloca() bytes get freed until you return from the function. So, if you have an nDataSize of 1024 and an iterations of 8, you'll allocate 8 kilobytes before returning. If you have an nDataSize = 65536 and iterations = 32768, you'll allocate a total 65536×32768=2,147,483,648 bytes, almost certainly blowing your stack and causing a crash.

Anecdote: You can easily get into trouble if you write past the end of the buffer, especially if you pass the buffer into another function, and that sub-function has the wrong idea about the buffer's length. I once fixed a rather amusing bug where we were using alloca() to create temporary storage for rendering a TrueType font glyph before sending it over to GPU memory. Our font library didn't account for the diacritic in the Swedish Å character when calculating glyph sizes, so it told us to allocate n bytes to store the glyph before rendering, and then actually rendered n+128 bytes. The extra 128 bytes wrote into the call stack, overwriting the return address and inducing a really painful nondeterministic crash!

8
  • 17
    @Neil Butterworth One of many reasons we don't actually use Standard C++ in embedded development. =P
    – Crashworks
    Commented Jun 13, 2011 at 19:13
  • 1
    what if I use it inside a recursive function? Are there any side effects? Also I don't understand that last part very well, "...blow up if you use it inside a loop". But a loop is still within a function right?
    – Mark
    Commented Jun 13, 2011 at 19:31
  • @Mark: If you execute alloca in a loop, it'll allocate more memory each iteration, but won't free the memory until you return from the function (whereas a container like std::vector local to the loop will be freed at the end of the loop's scope). Commented Jun 13, 2011 at 19:38
  • 5
    @Mark : Well, stop and think it through. What is alloca() doing, and how does the return type of a function affect it?
    – Crashworks
    Commented Jun 13, 2011 at 20:46
  • 4
    @Crashworks The link is broken and I want to read about your bug! Commented Nov 15, 2018 at 20:32
10

Since this is tagged C++, typically you just declare the objects you need in the correct scope. They are allocated on the stack, and guaranteed to be released on scope exit. This is RAII, and a critical advantage of C++ over C. No mallocs or news, and especially no allocas, required.

6
  • 2
    The problem here is that many C++ objects allocate memory for themselves.
    – Zan Lynx
    Commented Jun 13, 2011 at 19:13
  • @Zan Lynx - sure enough. In what scenario would you allocate such an object graph on the stack though? Commented Jun 13, 2011 at 19:15
  • 10
    You may call a function that fills in a vector. You might need a string. You might need these things to be very fast and thread safe. If you don't need these things to live beyond the function, then stack storage is exactly the right place.
    – Zan Lynx
    Commented Jun 13, 2011 at 19:21
  • @Zan - for specialized applications, I can see this. I think if OP had clarified why there is a perceived need for this, I'd be easier to convince. In most cases, my view is it's not needed. Commented Jun 13, 2011 at 19:24
  • @Steve - I work primarily in embedded environements and frequently my use of heap allocated memory is significantly constrained.
    – Greg
    Commented Sep 20, 2011 at 19:42
3

You can declare a local char[1024] or whatever number of bytes you'd like (up to a point), then take the address of the local for a pointer to this block of memory on the stack. Not exactly dynamic, but you could then wrap up this memory with your own memory manager if desired.

2
  • 1
    This should be the second best answer to that specific question if not the accepted answer. It's clean and simple, unlike the _alloca answer.
    – MarkoPaulo
    Commented Oct 27, 2017 at 21:30
  • 7
    @MarkusL.Clean simple and wrong because the question asks specifically about dynamic (not static) stack allocation.
    – jeremyong
    Commented Feb 26, 2019 at 20:33
3

Article discussing about dynamic memory allocation

We can allocate variable length space dynamically on stack memory by using function _alloca. This function allocates memory from the program stack. It simply takes number of bytes to be allocated and return void* to the allocated space just as malloc call. This allocated memory will be freed automatically on function exit.

So it need not to be freed explicitly. One has to keep in mind about allocation size here, as stack overflow exception may occur. Stack overflow exception handling can be used for such calls. In case of stack overflow exception one can use _resetstkoflw() to restore it back.

So our new code with _alloca would be :

int NewFunctionA()
{
   char* pszLineBuffer = (char*) _alloca(1024*sizeof(char));
    …..
  // Program logic
     ….
  //no need to free szLineBuffer
  return 1;
}
3
  • 2
    Welcome to SO! Consider quoting the most important bits in your answer, because links might rot.
    – Mateng
    Commented Nov 8, 2012 at 23:43
  • Hi, welcome to SO! Normaly a answer only pointing to another answer is not considered an answer. see meta.stackexchange.com/a/118694 for larification ;-) Commented Nov 8, 2012 at 23:43
  • Though alloca is one way of doing it, there are fair few drawbacks that makes it a bad practice. Please refer the discussion here; stackoverflow.com/a/1018865/83005 Commented Nov 8, 2012 at 23:43
3

See _malloca.​​​​​​​​​​​​​​​ ​

1
  • It is non-standard C++ one should mention
    – Sebastian
    Commented Jan 26, 2022 at 3:02
0

When/if C++ allows the use of (non-static) const values for array bounds, it will be easier.

For now, the best way I know of is via recursion. There are all kinds of clever tricks that can be done, but the easiest I know of is to have your routine declare a fixed-sized array, and fill and operate on what it has. When its done, if it needs more space to finish, it calls itself.

15
  • 2
    What question did you answer?
    – Daniel
    Commented Jun 13, 2011 at 19:13
  • Say what? C++ does allow const values for array bounds (if by that you mean array sizes).
    – user2100815
    Commented Jun 13, 2011 at 19:14
  • Neil Butterworth - lol, Does it? I learned on VC6, so occasionally I hit a "fact" that isn't really true. So you can eg: read an "array size" from a file into a size_t const and then use it as an array index size?
    – T.E.D.
    Commented Jun 13, 2011 at 19:17
  • @T.E.D.: no, you can't. If think Neil understood static const where you meant local const as in void f(const int n) { ... }. Commented Jun 13, 2011 at 19:20
  • @André Caron - Exactly. I wouldn't call it "obvious" either. Ada allows you to do this exact thing with no qualm whatsoever. Perhaps there is some reason why allowing the same would be injurious in C++, but from my perspective it appears an arbitrary limitation of the language. Until changed, the only standard way around it I know is to make the problem modular and use recursion.
    – T.E.D.
    Commented Jun 13, 2011 at 19:28
0

You could use the BDE C++ library, e.g.

const int BUFFER_SIZE = 1024;
char      buffer[BUFFER_SIZE];

bdlma::BufferedSequentialAllocator allocator(buffer, BUFFER_SIZE);
bsl::vector<int>                   dataVector(&allocator);

dataVector.resize(50);

BDE supplies comprehensive allocator options along with collections like bsl::vector that can use polymorphic allocators without changing the type of the container.

You might also consider:

Not the answer you're looking for? Browse other questions tagged or ask your own question.