TheSpiceMustFlow
TheSpiceMustFlow

Reputation: 43

Embedded C++: Initialization of an array member of a struct within a class, size omitted

Hello there and thanks in advance for any help on the following matter.

Edit: I forgot to add that this is on an embedded system with no access to STL features. My apologies for leaving this very important piece of information out. This is my first time coding in C++ extensively so I forgot to mention the obvious. I came back to add this fact and this question had already received some replies. Thank you all for such a quick response!

I am trying to initialize an array member of a struct that is in turn a public member of a C++ class. The array size is omitted in the struct. Here is an example:

// ClassA.h

Class A  
{
   public:

   struct StructA
   {
      StructB structs[];
   }; 

   struct StructB
   {
      // stuff
   };

   ClassA();
   //etc
};

// ClassB.h

ClassB: public ClassA
{

  public:

  StructA structA;

  ClassB()
  // etc
};

// ClassB.cpp

// What do I do here?  

I tried:

StructA ClassB::structA.structs[] = { first, second, third }

without any luck. I'm relatively new to C++ so this one has stumped me. I can add a size to the array member in StructA but I would rather not if there is a legal way to handle this.

Thanks!

Upvotes: 4

Views: 1233

Answers (4)

Mark B
Mark B

Reputation: 96251

You can't have unsized arrays in C++. Since you don't have access to vector:

  • If you know the maximum number of items you'll never need, just size your array to that value.
  • If you don't know the maximum number of items you'll never need, you'll have to dynamically manage your memory in some way. You can try new/delete by default but you may need to create your own memory pool if the defaults aren't performant enough.
  • If the very last line of your post indicates that you only ever need one copy of the array in the whole program, AND that you know what values to initialize to at compile time you can use a static class member. Your sample code had multiple problems so I had a hard time guessing what you wanted.

A sample of how the static would look though:

// ClassA.h

class ClassA
{
   public:

   struct StructB
   {
      // stuff
   };

   struct StructA
   {
      static StructB structs[];
   };


   ClassA();
   //etc
};

// ClassB.h

class ClassB: public ClassA
{

  public:

  StructA structA;

  ClassB() { }
  // etc
};

// ClassB.cpp

ClassA::StructB first, second, third;

// What do I do here?
ClassA::StructB ClassA::StructA::structs[] = { first, second, third };

int main()
{
    return 0;
}

Upvotes: 1

Lindydancer
Lindydancer

Reputation: 26104

In general, it's hard to create something that has a variable size in C or C++, without resorting to dynamic allocation, which you should try to avoid when using embedded systems.

I would suggest that you would create a plain array of things, and place a pointer to this inside your class. You can place the array in global scope, and the pointer does not have to know it's size.

In addition, by simply placing something in a class doesn't make it global. You must either make it a static member (meaning that there will be exactly one variable, regardless of how many objects of that particular class there is), or initialize it in the constructor.

For example:

class A
{
public:
  struct B
  {
    char const * str;
  };

  // Constructor
  A(A::B * beePointer)
    : mB(beePointer)
  {
  }

  // Data members
  B * mB;
};


// Global array
A::B my_Bees[] = {"first", "second", "third"};

A my_a(my_Bees);

Of course, in this solution, you can't add more elements to the end of the array, as it is allocated once and for all.

Upvotes: 1

Fred Foo
Fred Foo

Reputation: 363607

Arrays without a size aren't valid C++; they're a feature in C99, where they require some malloc magic to function. If you try to compile code using this feature with g++ -pedantic, you'll see that it emits:

$ g++ -Wall -pedantic test.cc
test.cc:5: error: ISO C++ forbids zero-size array 'foo'

I suggest you use std::vector instead, which has the same function as unsized arrays in C99 but is much safer:

std::vector<StructB> structs;

then add elements with push_back.

Upvotes: 7

zhengtonic
zhengtonic

Reputation: 730

Since you code in c++ anyway, why not use:

std::vector<structA> mStruct; ...
mStruct.push_back(first); ...

std::vectors are quiet comfortable in comparison to c-array and less error prone.

Upvotes: 2

Related Questions