I've got a variety of different PCBs each with an AtMega2560 microcontroller using a avr-gcc/ C compiler (using Arduino 1.8.12 compiler, which has classes, new, delete but not vector and such). My firmware is the same for all of the PCBs, which is really nice because a single EEPROM byte allows the PCB to select it's type and for all PCBs to run using the same firmware. But I've got memory problems and would like to not allocate the memory for non-instantiated classes. For example, 2 different types of PCBs might have large arrays with different allocations for different information:
voltateOutputPcb.h:
Class voltateOutputPcb
uint8_t outputVoltages[1000];
temperaturePCB.h:
Class temperaturePCB
uint32_t temperatureSensorReading[200];
The usage is nice and pretty. To get the 100th (0-indexed) outputVoltages_array element:
uint8_t 100thSensorValue = outputVoltages[100];
Option #1: Allocate memory during construction using pointers
If the code that selects both of these classes uses #include, the both big arrays are allocated on the stack at compile. I'd like to only allocate the memory of the one that is actually going to be instantiated. One way to do this would be to allocate a pointer and the create the array using new in the constructor:
voltageOutputPcb.h:
Class voltateOutputPcb
uint8_t *outputVoltages_array;
voltageOutputPcb.cpp constructor:
outputVoltages_array = new uint8_t[1000];
But usage is a bit ugly and could lead to future bugs. To get the 100th outputVoltages_array element:
uint8_t 100thSensorValue = *(outputVoltages_array+100);
Option #2: Separate versions of the code
Another option is to make a different compiled version of the firmware so that each PCB just has the .h files #included that it needs. This would be a manual process of doing multiple compiles and saving each different output file. This isn't ideal either, as it's really nice to have 1 piece of code, with details selected at run time.
Option #3: Shared memory
Having one big memory space that is allocated differently between the different instances is an option... but not a very good one here because the memory is being used for very different things. In this case I feel this is far inferior to Option #1 above.
Is there a better way?
Is there a better way to do dynamic allocation of memory on construction? Is there a less manual way to conditionally #include only what I want?
Some other relevant links:
Forward Declaration vs Include