How to create a very specific array

Ah ok I see. Thanks

The

Smagel:
The array and the instance of my class is needed for the entirety of the runtime so I don't need a deconstructor do I?

If you are 100% sure that you are never going to create local instances of your class, you don't need the destructor.
However, you might change your code in the future, and you might not think about that, introducing a memory leak.

If your class contains an owning pointer, you should probably also delete (or implement) the copy constructor and assignment. Otherwise, you can create copies of your object that share the same array, which is probably not what you want, especially if one of them is going to deallocate the memory eventually.

You could use something like this:

#include <FastLED.h>

/// Dynamic array of CRGB objects
class dyn_CRGB_array {
  public:
    /// Constructor.
    dyn_CRGB_array(size_t length) : data_(new CRGB[length]) {
      for (size_t i = 0; i < length; ++i)
        data_[i] = CRGB::Black;
    }
    /// Destructor.
    ~dyn_CRGB_array() { delete[] data_; }

    /// No copying allowed!
    dyn_CRGB_array(const dyn_CRGB_array &) = delete;
    dyn_CRGB_array &operator=(const dyn_CRGB_array &) = delete;

    /// Get a pointer to the underlying array.
    CRGB *data() { return data_; }
    const CRGB *data() const { return data_; }

    /// Get access to an element of the array.
    CRGB &operator[](size_t index) { return data_[index]; }
    const CRGB &operator[](size_t index) const { return data_[index]; }

  private:
    CRGB *data_;
};

constexpr uint8_t DATA_PIN = 7;

/// Example usage of the class above, based on your OctagonPanel class.
class OctagonPanel{
  public:
    OctagonPanel(unsigned int numLeds) : numLeds(numLeds), ledArray(numLeds) {}
    void begin() {
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(ledArray.data(), numLeds);
    }
    void show() {
      FastLED.show();
    }
    void setColor(CRGB color) {
      for (unsigned int i = 0; i < numLeds; ++i)
        ledArray[i] = color;
    }
        
  private:
    dyn_CRGB_array ledArray;
    unsigned int numLeds;
};

OctagonPanel panel(8);

void setup() {
  panel.begin();
}

void loop() {
  panel.setColor(CHSV(240, 255,255));
  panel.show();
  delay(1000);
  panel.setColor(CHSV(120, 255,255));
  panel.show();
  delay(1000);
}

I'd highly recommend implementing the destructor, unless you have a very good reason not to (e.g. out of flash space). If you do choose to omit it, add a clear comment indicating that the class leaks memory, so you don't forget when you revisit the project after some time.


The reason some people prefer to place the asterisk with the variable name rather than the type name is because of the following:

int* var1, var2;

Somewhat unexpectedly, the type of var1 is int* and the type of var2 is int (var2 is not a pointer).

If you want both variables to be a pointer, you need:

int *var1, *var2;

Other than that, it's mainly a personal preference, so just follow the conventions of the project if you're working in a team, or if it's a personal project, pick your favorite and stick to it.

Thanks for your advice PieterP!
I tried to wrap my head around the code you supplied but I suppose I'll have to ask someone at work to explain it to me thoroughly...

For now I added a couple of comments in all sections of the code that work with my array.

The piece of information on the pointer syntax is also valuable.

Thanks to everybody who answered! If i have more questions I'll open a new post so this one can be considered done.

What parts are you having trouble with?

The constructor uses a member initializer list, see Constructors and member initializer lists - cppreference.com.

The destructor just deletes/de-allocates the allocated memory.

The copy constructor and copy assignment operator are deleted, because otherwise, the compiler will provide a default copy constructor that copies the pointer to the data without actually copying the data, which will lead to hard to debug errors. Also see the rule of three/five: The rule of three/five/zero - cppreference.com.
Deleted functions are explained here: Function declaration - cppreference.com

Note: you have two choices here: either you implement a copy constructor that properly creates a copy of the data, or you delete it. Since you said that you'll only be using static, global instances of your class, you shouldn't need a working copy constructor, so the easiest way out is to simply delete the copy constructor, to prevent you from accidentally creating non-working copies.

The data() member function simply returns a pointer to the allocated array.

operator[](size_t index) defines the array subscript operator ([]), so you can write ledArray[index]. You need both a const and a non-const one: if the array itself is const, it returns a const reference to the element, if the array is mutable, it returns a mutable reference to the element. Idem for the data() function.

PieterP:
The constructor uses a member initializer list, see Constructors and member initializer lists - cppreference.com.
.
.
Deleted functions are explained here: Function declaration - cppreference.com

FWIW, I've always found everything at https://en.cppreference.com/ far too pedantic to be useful. It seems the authors are way more interested in formalism and the language specification than they are in providing useful explanations and examples.

Yes, you're right.
I think cppreference is really valuable, because it has all the information you need, while keeping it short (why waste 5 paragraphs if you can explain the same thing in 3 lines of formal notation?), but for the same reason, it's often hard to understand for beginners.

Do you know of any useful pages that are more beginner-friendly than cppreference?
Pages like geeks for geeks get a high ranking on Google search, but some pages I've read contained some questionable statements, so I don't feel confident enough recommending it or linking to it in threads like these unless I've fully read them.

The Microsoft docs seem to be a bit more readable than cppreference, but they might mention some MS Visual C++-specific stuff that doesn't apply to Arduino: