Arduino Forum

Using Arduino => Programming Questions => Topic started by: duckylock on Sep 14, 2019, 03:16 am

Title: LENGTH AND ARRAYS (how to deal with...)
Post by: duckylock on Sep 14, 2019, 03:16 am
Hi,
I have some issue to understand how arrays works
I tried that below:

Code: [Select]

float* getFloatArray() {
  float myfloatArr[5]={1.1,5.6,54.85,4.99,54.87};
  return myfloatArr;
};
char** getCharArrayList() {
  char* mycharArr[5]={"test","testdrtu","dgy","e","ghk"};
  return mycharArr;
};
int getFloatArraySize(float* floatArr) {
  return (sizeof(floatArr));
};
int getCharArraySize(char** charArrList) {
  return (sizeof(charArrList));
};
int getFloatArrayLength(float* floatArr) {
  return (sizeof(floatArr)/sizeof(floatArr[0]));
};
int getCharArrayLength(char** charArrList) {
  return (sizeof(charArrList)/sizeof(charArrList[0]));
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
 
  Serial.println("FLOAT* SAMPLE=={1.1,5.6,54.85,4.99,54.87}");
  float myfloatArray[5]={1.1,5.6,54.85,4.99,54.87};
  Serial.println("FLOAT* SIZE=="+String(sizeof(myfloatArray)/sizeof(myfloatArray[0])));
  Serial.println("FLOAT* LENGTH=="+String(sizeof(myfloatArray)));
 
  Serial.println("CHAR** SAMPLE=='test','testdrtu','dgy','e','ghk'");
  char* mycharArray[5]={"test","testdrtu","dgy","e","ghk"};
  Serial.println("CHAR** SIZE=="+String(sizeof(mycharArray)/sizeof(mycharArray[0])));
  Serial.println("CHAR* LENGTH=="+String(sizeof(mycharArray)));
 
  Serial.println("FLOAT* FROM FUNCTION SIZE=="+String(sizeof(getFloatArray())));
  Serial.println("FLOAT* FROM FUNCTION LENGTH=="+String(sizeof(getFloatArray())/sizeof(getFloatArray()[0])));
  Serial.println("CHAR** FROM FUNCTION SIZE=="+String(sizeof(getCharArrayList())));
  Serial.println("CHAR** FROM FUNCTION LENGTH=="+String(sizeof(getCharArrayList())/sizeof(getCharArrayList()[0])));
 
  Serial.println("FLOAT* INTO FUNCTION SIZE=="+String(getFloatArraySize(myfloatArray)));
  Serial.println("FLOAT* INTO FUNCTION LENGTH=="+String(getFloatArrayLength(myfloatArray)));
  Serial.println("CHAR** INTO FUNCTION SIZE=="+String(getCharArraySize(mycharArray)));
  Serial.println("CHAR** INTO FUNCTION LENGTH=="+String(getCharArrayLength(mycharArray)));
}



and my output is:

Code: [Select]

FLOAT* SAMPLE=={1.1,5.6,54.85,4.99,54.87}
FLOAT* SIZE==5
FLOAT* LENGTH==20
CHAR** SAMPLE=='test','testdrtu','dgy','e','ghk'
CHAR** SIZE==5
CHAR* LENGTH==20
FLOAT* FROM FUNCTION SIZE==4
FLOAT* FROM FUNCTION LENGTH==1
CHAR** FROM FUNCTION SIZE==4
CHAR** FROM FUNCTION LENGTH==1
FLOAT* INTO FUNCTION SIZE==4
FLOAT* INTO FUNCTION LENGTH==1
CHAR** INTO FUNCTION SIZE==4
CHAR** INTO FUNCTION LENGTH==1


has you can see, the size and length of my Float and String Arrays have different behaviors depending on the use of them.
Can you tell me what is the best practice and how to use Arrays and function.

Generally we make function to process data in Arrays or to get Arrays from a process, but it's quite complicated if we cannot have a constant array length information.
Can you help me.
Thanks
Title: Re: LENGTH AND ARRAYS (how to deal with...)
Post by: Delta_G on Sep 14, 2019, 03:27 am
Local variables are destroyed when the function exits.  If you return a pointer to one then it is still valid it just points to garbage. 

You can make those local arrays static with the static keyword so they persist or you can make them global. 
Title: Re: LENGTH AND ARRAYS (how to deal with...)
Post by: johnwasser on Sep 14, 2019, 07:04 pm
You should probably turn up the compiler warnings.  The compiler would then warn you about returning the address of a local variable and trying to take the size of an array argument.  Neither should be done but neither is strictly invalid syntax.

If you want to pass an array out of a function it can be a static local, global, or memory allocated on the stack which the caller is then required to 'free' when no longer needed.  The static and global cases mean that the next time you call the function it will overwrite the previous array.  In the allocated memory case you will have a 'memory leak' if the returned array is never freed.  Eventually the sketch will crash when memory fills up with arrays.

When an array is passed to a function it becomes a pointer, no matter how you declare the argument.  The pointer carries no information about how many elements the array contains.  If the function does not know how many elements, you have to pass that information as another argument.



Code: [Select]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino: In function 'float* getFloatArray()':
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:4:9: warning: address of local variable 'myfloatArr' returned [-Wreturn-local-addr]
   float myfloatArr[5] = {1.1, 5.6, 54.85, 4.99, 54.87};
         ^
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino: In function 'char** getCharArrayList()':
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:62: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   char* mycharArr[5] = {"test", "testdrtu", "dgy", "e", "ghk"};
                                                              ^
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:62: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:62: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:62: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:62: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:9:9: warning: address of local variable 'mycharArr' returned [-Wreturn-local-addr]
   char* mycharArr[5] = {"test", "testdrtu", "dgy", "e", "ghk"};
         ^
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino: In function 'void setup()':
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:40:64: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   char* mycharArray[5] = {"test", "testdrtu", "dgy", "e", "ghk"};
                                                                ^
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:40:64: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:40:64: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:40:64: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
/Users/john/Documents/Arduino/sketch_sep14a/sketch_sep14a.ino:40:64: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
Sketch uses 4456 bytes (13%) of program storage space. Maximum is 32256 bytes.
Global variables use 580 bytes (28%) of dynamic memory, leaving 1468 bytes for local variables. Maximum is 2048 bytes.
Title: Re: LENGTH AND ARRAYS (how to deal with...)
Post by: gfvalvo on Sep 14, 2019, 07:14 pm
The more stand way of doing it is to create the array in the calling function and pass a pointer (and usually array length) into the called function.
Title: Re: LENGTH AND ARRAYS (how to deal with...)
Post by: duckylock on Sep 14, 2019, 08:18 pm
Thank you everyone, I will try to apply all your advices and come back to you if something is not working or not understanable.