Serial.print Output changes the content of an array

Hi!
I have a function that is meant to return an array with 180 (NUM) values from 0-255. Those values are provided as the parameter modifier and returned as a pointer. When walk through this array like this:

...
#define NUM=190;
char modes[3];
...

void loop() {
char vals[15];
callMode(0,vals);
}

void callMode(int selectedMode, char vals[15]) {
 char matrixClr[NUM];

  char *matrixPointer;
 matrixPointer=getMatrixByMode(byte(modes[0]),1,vals);
//Serial Part 3
  for(int i=0; i<NUM;i++) {
    matrixClr[i]=matrixPointer[i];
  }
}
char* getMatrixByMode(int mode, int channel, char vals[15]) {
  int modificator=66;
  char* matrixArray;
  char myArray[NUM];
  switch(mode) {
    case 65:
      matrixArray=styleSingle(vals,modificator);
      for(int i=0; i<NUM;i++) {
        myArray[i]=matrixArray[i];
      }
//Serial Part 2
       for(int i=0; i<NUM;i++) {
        Serial.print(myArray[i]);
      }
      Serial.println("");
      break;
  }
  return myArray;
    
}
char *styleSingle(char musicVals[15], uint8_t modifier) {
  char matrix[NUM];
   for(int i=0;i<NUM;i++) {
       matrix[i]=modifier;
     }
//Serial Part 1
     for(int i=0;i<NUM;i++) {
       Serial.print(matrix[i]);
     }
     Serial.println("---");
     return matrix;
}

When I remove the code in Serial Part 1 it still works as long as i keep the code underneath Serial Part 2. If I remove that code as well I get a different result.

EXPECTED RESULT: Is a row with 190 B's (as B is the Value for 66). This result is achieved when Serial Part 1 or Part 2 is left inside the code.

RESULT WITHOUT Serial.print loops as underneath //Serial Part 1/2 : Something like this:
:dÿÿ¾2?h?>?ØÀFH2»LQ?b«KBABSVARSVARS:SAT=BRI=CL

and that is not equal to BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB...

Does anyone have an idea what causes this strange behavior? I suspect it to be some sort of memory issue or pointer based problem, but I can't seem to get it fixed. In previous versions I passed the pointer directly in the getMatrixByMode, but that did not work either, so i added myMatrix[] since I thought this way the values would be copied to a different space in memory, but that doesn't seem to work either.

On a side-note: In a previous Version I was not using getMatrixByMode but I requested the matrix directly in callMode like so:

void callMode(int selectedMode, char vals[15]) {
switch(selectedMode) {
    case MODE_KILLER:
     
      copyMatrix(styleSingle(musicVals, sSaturation),2);
      break;
}

and that always worked. Problems seem to start with getMatrixByMode, but I can't see what I'm doing wrong.

Statistics:
I am on an Arduino Mega using this code to check on free RAM:

int freeRam () 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

It returns some 5k+ RAM available, and it seems legit to me. Entire code size is 20k (256k available)
Need your help :wink:

#define NUM=190;

I see problems.

Why not just attach the real code?

The getMatrixByMode function is returning a pointer to myArray[] which only exists within the getMatrixByMode function. The array needs to be global or at least scoped such that the calling function(s) still sees it.

Pete

char* getMatrixByMode(int mode, int channel, char vals[15]) {
  int modificator=66;
  char* matrixArray;
  char myArray[NUM];
  switch(mode) {
    case 65:
      matrixArray=styleSingle(vals,modificator);
      for(int i=0; i<NUM;i++) {
        myArray[i]=matrixArray[i];
      }
//Serial Part 2
       for(int i=0; i<NUM;i++) {
        Serial.print(myArray[i]);
      }
      Serial.println("");
      break;
  }
  return myArray;
    
}

The above is complete rubbish. It makes no sense to return a pointer to something on the stack. When a function ends every thing it put on the stack is freed up for reuse.

The same comment applies to most fo your function. Also look up the concept of "scope".

Mark

If it weren't 'rubbish' I wouldn't need any help. Apart from that I wonder if someone would give me a quick example of how I would correctly write a function that returns an array? I seem to not have understood this correctly. Of course I could do it this way:

char matrix[190];

void changeMatrix(int value) {
  for(int i=0; i<190;i++) {
    matrix[i]=value;
 }
}

But that is not what i want as you can see. So my question is: how is it possible to pass the values from singleStyle to callMode without the necessity of declaring all globally?

AWOL: I think it'd only confuse as my problem is only the concept of the memory allocation and the visibility.

Pass a pointer to the array:

void changeMatrix(const int size, const int value, char * matrix) 
{
  for(int i=0; i<size;i++) 
  {
    matrix[i]=value;
  }
}

void setup () { }

void loop ()
{
  char matrix[190];
  changeMatrix (sizeof matrix, 42, matrix);
}  // end of loop

If you want to get fancier, use templates, and pass the array by reference:

template <typename T, size_t N > 
void changeMatrix(const T value, T (&matrix) [N]) 
{
  for (size_t i = 0; i < N; i++) 
  {
    matrix [i] = value;
  }  // end of for
} // end of changeMatrix

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  }  // end of setup

void loop ()
{
  char matrix[190];
  changeMatrix ((char) 42, matrix);
  
  for (int i = 0; i < sizeof matrix; i++)
    Serial.println ((int) matrix [i]);
    
  while (true ) ;
}  // end of loop

Now the templated function "knows" the size of the array, so you don't have to pass it down. Plus the array can be of any type (within reason).

Thank you Nick, exactly what I wanted to know.

AWOL: I think it'd only confuse as my problem is only the concept of the memory allocation and the visibility.

What is confusing is when you post something that cannot compile, and tell us you've got a problem when it runs.