20

I'd like to make three arrays of the same length. According to the documentation, Arrays must be defined as int myArray[10]; where 10 can be substituted for a known length (another integer), or filled with an array {2, 3, 5, 6, 7}.

However, when I attempted to declare a value int arrSize = 10; and then an array based on that size int myArray[arrSize];, I get the following: error: array bound is not an integer constant.

Is there a way to variably determine array sizes, or do I just need to hardcode them? (I was taught hardcoding is bad and something to avoid at all costs.)

1
  • I had a similar problem and did this. I am learning too so can't say if it is valid solution or not but it worked. See below part of code using vectors, it took me quite a bit to start to understand them and I am still not an expert by no means: #include <string> #include <vector> #include <iostream> #include <algorithm> #include <string.h> using namespace std; int main() { string name; string address; string town; string country; string answer; vector<vector<string>> personData; for(;;) { vector<string> myTempData; cout<<"enter name or n to exit"<<endl; getline(cin, name); if(name=="n") { bre
    – Misterxp
    Oct 25, 2017 at 20:03

5 Answers 5

29

Your question has 2 parts actually.

1/ How can I declare the constant size of an array outside the array?

You can either use a macro

#define ARRAY_SIZE 10
...
int myArray[ARRAY_SIZE];

or use a constant

const int ARRAY_SIZE = 10;
...
int myArray[ARRAY_SIZE];

if you initialized the array and you need to know its size then you can do:

int myArray[] = {1, 2, 3, 4, 5};
const int ARRAY_SIZE = sizeof(myArray) / sizeof(int);

the second sizeof is on the type of each element of your array, here int.

2/ How can I have an array which size is dynamic (i.e. not known until runtime)?

For that you will need dynamic allocation, which works on Arduino, but is generally not advised as this can cause the "heap" to become fragmented.

You can do (C way):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source)
if (myArray != 0) {
    myArray = (int*) realloc(myArray, size * sizeof(int));
} else {
    myArray = (int*) malloc(size * sizeof(int));
}

Or (C++ way):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source or through other program logic)
if (myArray != 0) {
    delete [] myArray;
}
myArray = new int [size];

For more about problems with heap fragmentation, you can refer to this question.

4
  • 4
    1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, this way you can change the type of myArray without introducing bugs. For the same reason, myArray = realloc(myArray, size * sizeof *myArray);. BTW, casting the return value of malloc() or realloc() is useless also. 2) Checking for myArray != 0 in the C version is useless, as realloc(NULL, sz) is equivalent to malloc(sz). May 20, 2015 at 17:47
  • const int ARRAY_SIZE = 10; int myArray[ARRAY_SIZE]; Do you really think it is possible?. This would give variably modified array error in C. Aug 6, 2018 at 14:44
  • @ArunCheriyan in C I don't know, but in C++ it compiles and runs perfectly. Since Arduino is C++ based, then there is no issue here.
    – jfpoilpret
    Aug 6, 2018 at 17:53
  • There could be one reason to use dynamic memory safely on an Arduino, which is when you DON'T delete that memory and reuse it anymore, so just for 'initialization' purposes. You just have to make sure that the total amount of dynamic memory is enough to leave space for other dynamic memory (including function/methods arguments which land on the stack). Jun 15, 2021 at 16:03
2

I know I'm a little late here, but in theory regular arrays can't be created using a variable to define the amount of elements the array is going to have as in:

int arrSize;
int myArray[arrSize];

This will display an error since when declaring the array, the program expects for the value between the brackets to be a constant. Yet, there is a way in which you could create an array with a variable defining the amount of values this arrays is going to have through dynamic memory allocation for value sets (this method has been tested with monodimensional arrays only, haven't tried for multidimensional yet), and it goes something like this:

//First you create a pointer for the memory space to be separated for the set you're creating
int* myArray;
int arrSize; //Then you define the variable that will determine the amount of elements the array is going to have, you can give it a value whenever you want as long as this int is defined before the values in myArray are set 
myArray=(int*)calloc(arrSize,sizeof(int)) //Here, you establish that the instance myArray (whose memory space has already been separated through the creation of the pointer) will be separated into arrSize amount of elements of type int with a maximum memory value (in bytes) equal to the maximum available for the int type variables

After this, all that's left to do is assign a value for every element created in the instance myArray (which is already an Array by now) as you would for a normal array created as myArray[arrSize].

1

If you know the maximum length of array, just initialize the array to that length and use an integer to tell the program how much of that array to use. If it's the difference between 7,10 bytes then you are not wasting that much memory allocation.

0

The size of the array must be known at compile time. Otherwise you should allocate memory dynamically using:

char *chararray = malloc(sizeof(char)*x);

where x(an integer) can be set in the application code (you could load it from eeprom if you wanted it be a persistent but configurable setting).


However if you just want to declare some arrays of the same size, you just have to declare the number a constant like this:

const int arrsize = 10;
char array1[arrsize];
int array2[arrsize];

I think not hardcoding things only makes sense if you would reasonably expect the user to want to change the setting at some point. I don't know if that's the case.

2
  • Coding sizes symbolically instead of literally can provide two benefits: 1) A well chosen symbol documents, or at least suggests, the reason for the choice; and 2) when other parts of the program or module need to be tailored to that choice, an expression using the same symbol can make that automatic, making maintenance much easier.
    – JRobert
    May 20, 2015 at 17:32
  • [A bit off topic, but] "user" is ambiguous as it can mean one of a number of people. It usually implies the end user, the consumer of final product, if not stated otherwise. It could be the next programmer, the immediately next consumer of your code, who might, in fact, be you (typical, in my own experience) a year or more after I've forgotten the nitty-gritty internal details of it). Or a system designer who includes your code as a ready-to-go module in his/her product. I suspect you meant the second "user".
    – JRobert
    May 20, 2015 at 17:39
0

The coderwall explains in Some detail the theory of how best to get the size of an array in C++ https://coderwall.com/p/nb9ngq/better-getting-array-size-in-c

2
  • 2
    Hi John, welcome to Arduino Stack Exchange! We have a general rule that answers should not just be links, as links do (unfortunately) go down and then the answer is useless. Please summarize, or re-post, the information in the answer right here (I notice it is quite short) so that the usefulness of it doesn't go away. I suggest you give credit by linking to the site, or the name of the author, or both.
    – Nick Gammon
    Oct 14, 2020 at 20:53
  • 1
    It's better to include your own short answer and only referencing the source. Otherwise the answer is of no help when the website you link to gets removed.
    – Sim Son
    Oct 14, 2020 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.