0

guys.

I'm writing here because I cannot find an obvious error, so I'm stuck. Could you please help me?

Here's the code:

int arrayAAA[] = {6, 8, 10, 12};
int arrayBBB[] = {9, 15, 27, 41};

const int arrayAAALength = sizeof(arrayAAA)/sizeof(int);
const int arrayBBBLength = sizeof(arrayBBB)/sizeof(int);

int newArrayLength = 0;

void setup() {

    Serial.begin(9600);

}

void loop() {

  String dir = "AAA";

  if (dir == "AAA"){

      //Copy existing array to the new one...
      newArrayLength = arrayAAALength;              //Get the size of source array
      int newArray[newArrayLength];                 //Make the new array of the same size
      memcpy(newArray, arrayAAA, sizeof(arrayAAA)); //Copy content of the source array to the new one

      /*
      for (int i = 0; i < newArrayLength; i++){
          Serial.print(newArray[i]); //Here everything works just fine...
          Serial.print("   ");
      }
       */    
  }

  for (int i = 0; i < newArrayLength; i++){
      Serial.print(newArray[i]); //But here I see this error: 'newArray' was not declared in this scope
      Serial.print("   ");
  }

  Serial.println();
  Serial.println();

}

What I'm trying to do is to copy the array to a new one, but depending on the circumstances I need to take different source arrays (AAA or BBB).

The problem is in checking the values of an newly crreated array:

'newArray' was not declared in this scope

if I try to check its valus outside of if statment.

It seems my stupid mistake, but I can't find it.

3 Answers 3

1

After a careful study of C/C++ documentation, I finally managed to use pointers in Arduino :)

So, the final code became like this:

int arrayAAA[] = {6, 8, 10, 12};
int arrayBBB[] = {9, 15, 27, 41};

//Create a pointer, which will point to any of your arrays of your choice
int *newArray; 

const int arrayAAALength = sizeof(arrayAAA)/sizeof(int);
const int arrayBBBLength = sizeof(arrayBBB)/sizeof(int);

void setup() {

    Serial.begin(9600);

    //Uses the address of arrayAAA (i.e. inherits the content of arrayAAA). 
    //&: points to address of a chosen array.
    //[0]: is a must to grab all values!
    newArray = &arrayAAA[0]; 

    Serial.print("arrayAAA:");
    for (int i = 0; i < arrayAAALength; i++){
        Serial.print("   ");
        Serial.print(arrayAAA[i]);
    }
    Serial.println();

    Serial.print("newArray:");
    for (int i = 0; i < arrayAAALength; i++){
        Serial.print("   ");
        Serial.print(newArray[i]);
    }
    Serial.println();
}

void loop(){
    //Left empty
}

And it works perfectly, just what I expected!

0

The clue is in the indenting:

  if (dir == "AAA"){

      //Copy existing array to the new one...
      newArrayLength = arrayAAALength;              //Get the size of source array
      int newArray[newArrayLength];                 //Make the new array of the same size <<<==== DEFINED IN THE SCOPE OF "IF"
      memcpy(newArray, arrayAAA, sizeof(arrayAAA)); //Copy content of the source array to the new one

      /*
      for (int i = 0; i < newArrayLength; i++){
          Serial.print(newArray[i]); //Here everything works just fine...
          Serial.print("   ");
      }
       */    
  }

  for (int i = 0; i < newArrayLength; i++){
      Serial.print(newArray[i]); //But here I see this error: 'newArray' was not declared in this scope <<=== USED IN THE SCOPE OF "FOR"
      Serial.print("   ");
  }

As you can see by the indenting the definition of newArray is in a different block of code which you come right out of before you use it.

You must define newArray at a scope that is outside where you use it.

From that code you don't actually need to copy the contents of one array into another - you can just point to the array you want to use with a pointer. Alternatively, if you do need to clone the array contents (for some other purpose we don't know of) then you should pre-create an array that is big enough to hold either of your other arrays.

int newArray[max(arrayAAALength, arrayBBBLength)];
5
  • Yes, I'd like to point to another array. This would be much more effective. But how can I do it right? I tried to use this code: int *newArray = &arrayAAA, but it leads to another error: invalid types 'int[int]' for array subscript. Commented Jun 8, 2016 at 17:51
  • It's a very bad idea to create arrays on the stack in the way you describe. If you want a run-time-sized array, use std::vector. If you must have an array, use unique_ptr<int[]>, which will take care of deallocating the space when the variable gets out of scope. Adding examples as an answer so I can format them properly Commented Jun 8, 2016 at 21:47
  • (as to why it's a bad idea: it usually adversely affects caching, and may blow your stack, which is a real concern in some memory-constrained systems, or in massively multithreaded environments where you really want to use the smallest stack frame possible. While the arduino isn't such an environment, habits you acquire here may transfer to other jobs, and then you'll be trying to find really insidious bugs which could have been prevented by proper code hygiene.). Commented Jun 8, 2016 at 22:00
  • @JayEye Sorry, but your thinking is wrong there. On a memory constrained system like the Arduino it is far better to use the stack than the heap. The stack is a LIFO system so all allocation / deallocation is linear. Using the heap leads to fragmentation, and on a system that has no ability to do heap defragmentation even slight amounts of fragmentation can lead to big problems further down the line as the heap grows out of control. You don't get that with the stack. And with no frame swapping, since there is no OS or threads or anything like that, you don't get any performance hit ... Commented Jun 9, 2016 at 11:29
  • ... by having a large frame. Yes, it is possible to smash your stack into the heap, but it's easier to avoid than the tangled mess of swiss cheese that the heap would become from growing up into the stack. In general dynamic allocation on a small MCU is frowned upon. Also many MCU compilers don't even have STL available for use - simply because it is too heavyweight and causes too many heap problems for reliable use. Yes, your comments are perfectly valid in other environments and other situations, but not for tiny MCUs like the Arduino. Commented Jun 9, 2016 at 11:31
-1

Made corrections per @Majenko's comment

The following will not work on real Arduinos, but it did work for me on the ESP8266 and the Teensy3, which are what I use mostly, and the only ones I tested the code for: https://github.com/jayeye/jardino/tree/master/esp8266/ase25017

#include <vector>
  ...
  size_t vector_size = 42;
  std::vector<int> foo(vector_size);  // foo is a vector of 42 integers

Another correction: Exceptions do not work even on the aforementioned platforms, so do not access the vector with .at(n)

If you must have an array, use a unique_ptr with an array allocator:

#include <memory>
  ...
  size_t vector_size = 42;
  std::unique_ptr<int[]> arr(new int[vector_size]);

When arr goes out of scope, the array will be automatically freed.

You can always use malloc(), but you'll have to remember to free() it, and that's always a source of bugs.

3
  • 1
    That can't work on an Arduino. There is no STL, and hence no vector. Also... If you want to get an exception - what is an exception? There are no exceptions. You are thinking PC programming, not MCU programming. The two are vastly different and take completely different mindsets. Commented Jun 9, 2016 at 11:35
  • Two lessons here: test on the most common platform (I had tested the code on the esp8266, which is what I had handy at the moment), and don't make assertions without testing them (about exceptions -- I never use them, they are forbidden by the Google style guide, and for good reason, but I tried to be too smart here and failed :) ) Commented Jun 9, 2016 at 18:05
  • also, what's this "PC programming". I don't program PCs, I program large linux clusters :) Commented Jun 9, 2016 at 18:06

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.