Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++17

C/C++: Allocate Variable-size Arrays on the Stack

0.00/5 (No votes)
25 May 2020CPOL2 min read 14.1K  
How to allocate variable-size arrays on the Stack in C/C++
This tip will show you how to allocate variable-size arrays on the stack to be used with C++17 containers.

Introduction

C language provides the alloca function to allocate arbitrary size array on the stack. After the function returns or the scope ends, the stack memory is automatically reclaimed back (popped back) without the developer having to deallocate it explicitly and thereafter is unsafe to access it again from another function. The below code shows allocating fixed size and arbitrary size stack memory. While arbitrary size stack memory has flexibility, care has to be taken that not too much is allocated to exhaust all the available stack memory (default is 1MB), especially if the developer is writing a library and has no control over how his library is used. For instance, his library may be used in a worker thread with only 10KB of stack memory.

C++
// allocate fixed-length memory on the stack:
int buf[10];

// allocate arbitrary-length memory on the stack:
char* buf = (char*)alloca(10 * sizeof(int));

Starting from C++17, it is possible to specify a memory buffer to be used for containers in the std::pmr namespace. PMR stands for Polymorphic Memory Resources. Though containers in std and std::pmr namespace have similar interface, they are not interchangeable. To use std::pmr containers such as string and vector, C++17 has to be enabled first in the Visual C++ project properties. See screenshot below.

Image 1

The std::pmr::string example allocates a buffer with alloca and passes it to monotonic_buffer_resource which is then passed into the std::pmr::string.

C++
#include <iostream>
#include <string>
#include <memory_resource>

// allocate some memory on the stack:
char* buf = (char*)alloca(200);

std::pmr::monotonic_buffer_resource pool{ buf, 200 };
std::pmr::string str{ &pool };

str = "just a non-SSO string";

std::cout << str << std::endl;

The std::pmr::vector example allocates on the stack and construct monotonic_buffer_resource, with that buffer. The std::pmr::vector takes in the monotonic_buffer_resource.

C++
#include <iostream>
#include <vector>
#include <string>
#include <memory_resource>

// allocate some memory on the stack:
char* buf = (char*)alloca(200000);

// and use it as initial memory pool for a vector:
std::pmr::monotonic_buffer_resource pool{ buf, 200000 };
std::pmr::vector<std::string> coll{ &pool };

for (int i = 0; i < 1000; ++i) {
    coll.emplace_back("just a non-SSO string");
}

What happens when the PMR container runs out of the assigned memory buffer? It shall allocate on the heap or the upstream memory resource specified at its constructor.

C# stackalloc

Interestingly, C# also has a similar feature such as the stackalloc keyword that allocates on the stack as opposed to the new keyword which allocates on the heap through the Garbage Collector (GC).

C#
int length = 3;
Span<int> numbers = stackalloc int[length];
for (var i = 0; i < length; i++)
{
    numbers[i] = i;
}

Reference

History

  • 25th May, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)