Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Flexible Array in Arduino ?

  1. #1
    Senior Member Jp3141's Avatar
    Join Date
    Nov 2012
    Posts
    486

    Flexible Array in Arduino ?

    I am trying to initialize an array as part of a structure variable, but the compiler options in place on Arduino seem to require that the array size is predefined. Is there a way around this ? Ultimately, different instances of my Key structs will have different lengths for the Pulse[] array and I don't want to reserve memory for the worst (longest) case.

    Here is a very reduced version of my code;

    Code:
    struct Key {
      char Name[8];
      unsigned int Pulse[11]; // works
      //unsigned int Pulse[];   // get compiler message about "too many initializers for 'unsigned int [0]'"
    }; 
    
    struct Key OnKey =     {"On",     {9070,4480, 610,530, 600,530, 610,520, 600,530, 00}};
    
    void setup() {} 
    
    void loop() { }

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,074
    Quote Originally Posted by Jp3141 View Post
    Is there a way around this ?
    There is no easy way. Arrays in C++ are fixed length.

    You can create a C++ class, which isn't really an array at all, but tries to act like one with operator overloading syntax. Then code inside your class can use malloc or new to dynamically allocate memory as needed. Arduino's String class does this, if you need an example for inspiration.

    Many people consider use of malloc/new controversial for embedded code, due to possible memory fragmentation and non-deterministic timing. Those might be issue to consider in the design of your special C++ class, should you decide to go down that path.

  3. #3
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    732
    I’ve been playing around with new and delete for creating variable wavetable arrays from an SD card for dynamic wavetable synthesis instead of being limited to what fits in flash memory. Caution definitely needs to be taken place to make sure there are no memory leaks or collisions, but it is possible although like Paul says it’s controversial for microcontrollers.

  4. #4
    Senior Member JarkkoL's Avatar
    Join Date
    Jul 2013
    Posts
    117
    you could do something along the lines of:
    Code:
    struct Key {
      char Name[8];
      unsigned int *Pulse;
    }; 
    
    unsigned int pulseOn[]={9070,4480, 610,530, 600,530, 610,520, 600,530, 00};
    Key keyOn = {"On", pulseOn};

  5. #5
    Senior Member Jp3141's Avatar
    Join Date
    Nov 2012
    Posts
    486
    Thanks @JarkkoL -- that's closer to what I was aiming for, but I was hoping (for clarity) to have it all on one line without having to invent new names for all the intermediate variables like pulseOn[] -- I'll have a couple of dozen of those.

    I guess C can't do something like:

    Code:
    Key keyOn = {"On", &{9070,4480, 610,530, 600,530, 610,520, 600,530, 00}};
    where the address of the list of integers is added to the structure ? ( but I guess that is what is happing with the string for the Name ?)

    Also, the
    Code:
     pulse[]
    syntax and
    Code:
    Key OnKey =     {"On",     {9070,4480, 610,530, 600,530, 610,520, 600,530, 00}};
    work on gcc on my Mac. It seems to be a feature of C99 -- does Arduino use that ?
    Last edited by Jp3141; 12-15-2019 at 01:47 AM.

  6. #6
    Senior Member JarkkoL's Avatar
    Join Date
    Jul 2013
    Posts
    117
    Well, if you absolutely want to take a trip to the syntax crazy land:
    Code:
    #define KEY(name__, ...) unsigned int pulse##name__[]=__VA_ARGS__;\
                             Key key##name__={#name__, pulse##name__}
    
    KEY(On, {9070,4480, 610,530, 600,530, 610,520, 600,530, 00});
    Edit: Just to clarify, I don't advocate this kind of code because it silently introduces new identifiers to your code and causes extra indirection that you mentally have to jump through when reading code... just to make the syntax appear slightly cleaner outside. IOW, it's a bad compromise, IMO
    Last edited by JarkkoL; 12-15-2019 at 02:06 AM.

  7. #7
    Senior Member Jp3141's Avatar
    Join Date
    Nov 2012
    Posts
    486
    Thanks -- that works, but I agree it's quite twisted; I'll wait until I am really out of memory.

  8. #8
    Senior Member
    Join Date
    Sep 2020
    Location
    Massachusetts
    Posts
    115
    I'm running into the same old problem I always run into when I want to combine web tech with embedded tech. We have JSON support in C++, but I can't do the essential things I really want to do with JSON: gimme a dynamically-generated collection of keys from a foreign JSON object and tell me what's inside. (dynamic reflection of the contents of a property bag)

    That's where things fall down. If I am using big dumb Microsoft C++ frameworks, or even STL, I can get these dynamic collection classes and not worry about their lifecycles, etc.

    But that's web-style thinking: I'm handing my program a blob of loosely-typed data with no schema. My program's job is to identify parts of the blob it can use, without a schema. {"shoes": 3, "hats": 4} If blob has hats, do hat stuff, if blob has hotdogs, do hotdog stuff, and if hotdogs are not given, don't die a horrible death. (old-school web thinking: no dtd? DIEEEE)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •