1

I'm new to optimization in C++. I have read that stack allocated memory can be much faster than heap allocated memory.

I also have read that std::array is stack allocated, but most other containers, like std::vector or dynamic arrays are heap allocated. I'd like to define a class which essentially just stores an array of doubles. I intend for all instances of the class to have the same dimension, and that I can calculate what that dimension will be at compile time. The catch is that I would like to do the computation of that dimension in main.cpp instead of in the class.cpp. That means trying something like the following:

class.h:
extern constexpr dimension;

and,

class.cpp:
class Coordinates {
    public std::array<double, dimension> q{}; 
}

and then

main.cpp:
#include "class.h"
constexpr dimension = 2*3*100

Now, extern constexpr dimension is nonsense as the translation unit will not know what the value of dimension is at compile time.

Is there a way to have a stack-allocated array type object with dimension defined in another translation unit? Would it even be worth it?

denomme
  • 13
  • 2
  • How about vector with stack allocator? Using alloca()? – Severin Pappadeux Mar 26 '21 at 18:47
  • Best thing I can think of is `main` allocates the array, since only it knows the size, and provides it to the object on construction. I think you're stuck on this one. – user4581301 Mar 26 '21 at 18:48
  • I strongly doubt std::array is stack allocated because you would have to somehow pass the result of alloca() to the std::array<> object. Where did you hear such information? That being said you can stack allocate almost anything with the correct in-place constructor and alloca(). STL doesn't support stack allocation because it is a very dangerous practice. – David Bien Mar 26 '21 at 18:50
  • 1
    `std::array` can be allocated anywhere. Could be stack, could be static storage, could be dynamic storage (`new std::array<>`) – SergeyA Mar 26 '21 at 18:53
  • Sheeeooot. I'm dumb. Can you make `Coordinates` a template? – user4581301 Mar 26 '21 at 18:53
  • 1
    "I intend for all instances of the class to have the same dimension" then use template class Coordinates{} – huseyin tugrul buyukisik Mar 26 '21 at 18:54
  • Aside: You've just found one of the reasons using stack and heap instead of automatic and dynamic can cause problems. – user4581301 Mar 26 '21 at 18:56
  • Before you go wild with performance tuning, the first step is to benchmark – AndyG Mar 26 '21 at 19:09
  • @DavidBien I found the remark about stack allocation [here](https://stackoverflow.com/a/39549597/15488679) Are you referring to stack overflow when you say allocating to the stack is dangerous, or pointers going out of scope, or something else? – denomme Mar 26 '21 at 23:31
  • @denomme Oh, ok, I misunderstood. All the means is that std::array<>, since it is a fixed-size array, doesn't allocate dynamic memory internally. So if you declare it as a local, then all of its memory is in the stack. This doesn't use alloca() - this is just how local variables work. – David Bien Mar 27 '21 at 00:34

1 Answers1

0

You are asking for a template:

template<int dimension>
struct Coordinates {
    std::array<double, dimension> q{}; 
};

Usage:

int main()
{
    constexpr auto dimension = 2*3*100;
    Coordinates<dimension> c;
    c.q[0] = 1;
    c.q[1] = 2;
    // ...
}

Demo

AndyG
  • 39,700
  • 8
  • 109
  • 143
  • This does exactly what I was asking for! I didn't realize that templates can be non-type variables. This advantage (static allocation instead of dynamic) is pointed out in this article on the topic: [learncpp reference](https://www.learncpp.com/cpp-tutorial/template-non-type-parameters/) – denomme Mar 27 '21 at 03:44