Go Down

Topic: How do you check the Length of an Array? (Read 2275 times) previous topic - next topic

PeterH


Looks like you need pedantic warnings:



I'm surprised that the compiler accepted that code.

I'm even more surprised what happens if you put a delay() in:
Code: [Select]

int i;

void setup()
{
  Serial.begin(9600);

  delay(50);
 
  i = millis();
  char global[i];   
  Serial.println(sizeof (global));

  int j = millis();
  char local[j];   
  Serial.println(sizeof (local));
}
void loop()
{
}


Quote from: sketch

49
52


Um, is it allowed to do that?
I only provide help via the forum - please do not contact me for private consultancy.

ajofscott

I'm suprised he had any RAM left after dimensioning an array to the return from millis().

AWOL

Why are you surprised?
Read the code again.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

lloyddean

#18
Feb 05, 2012, 12:23 am Last Edit: Feb 05, 2012, 12:27 am by lloyddean Reason: 1
C++ allows the size of stack based arrays to be dynamically stated (within the limits of stack size), but not resized.  It is valid code.

westfw

Note, by the way, that you can not use the "sizeof" operator on arrays that have been passed to a function, since arrays are always passed  by reference (a pointer), and the size of a pointer is always 2.
Code: [Select]
int myarray[15];
void loop() {
  operate(myarray);
}
void operate(int arr[])
{
  Serial.print(sizeof(arr));
}

Will print "2."

Yes, there are reasons to support things like dynamically sized arrays, and arrays that contain information about their actual size.  But the C language doesn't support either one; it's a "primitive" language.

Nick Gammon


C++ allows the size of stack based arrays to be dynamically stated (within the limits of stack size), but not resized.  It is valid code.


Well, you learn something new every day! I didn't know you could do that. :)
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PeterH


Well, you learn something new every day! I didn't know you could do that. :)


Nor me, although to be fair my 'C' is a few decades rusty and my C++ coding has all been pretty mundane stuff.

How is 'sizeof' worked out, then? I thought this was a compile time expression. Is the compiler creating an honorary class and using rtti, or something?
I only provide help via the forum - please do not contact me for private consultancy.

wh33t

Well, this whole conversation has gone well over my head in terms of what I can personally relate to, but I get that the general answer is that there isn't a simple function I can call that will return the number of indexes in an Array.

I'm glad people are having good discussion.

I'm sure I will have many more questions soon. Going from a very high level language such as PHP to ... whatever it is that Arduino uses (it's C right?) certainly has it's challenges. I'm only just beginning to realize how much processing power and ram a modern day web server actually has. Kind of boggles my mind!

Nick Gammon

Well this is interesting:

Code: [Select]
char array[i];
  f0: 2d b7        in r18, 0x3d ; 61
  f2: 3e b7        in r19, 0x3e ; 62
  f4: 26 1b        sub r18, r22
  f6: 37 0b        sbc r19, r23
  f8: 0f b6        in r0, 0x3f ; 63
  fa: f8 94        cli
  fc: 3e bf        out 0x3e, r19 ; 62
  fe: 0f be        out 0x3f, r0 ; 63


I bet you didn't realize that doing this:

Code: [Select]
char array[i];

... fiddled with the interrupt enable flag. :)

Quote
How is 'sizeof' worked out, then? I thought this was a compile time expression. Is the compiler creating an honorary class and using rtti, or something?


Well the mind boggles a bit here too, but it appears that the compiler has saved the size of the array into temporary registers and passed that (in this case) to Serial.println().
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

westfw

Quote
fiddled with the interrupt enable flag?

it has to, since it modifies the 16bit stack pointer one byte at a time:
Code: [Select]
  f0: 2d b7        in r18, 0x3d ; read stack pointer low byte
  f2: 3e b7        in r19, 0x3e ;  stack pointer high byte
  f4: 26 1b        sub r18, r22   ; create stack frame by
  f6: 37 0b        sbc r19, r23   ;   adjusting SP
  f8: 0f b6        in r0, 0x3f ; get status register
  fa: f8 94        cli       ;; don't want interrupts while writing SP
  fc: 3e bf        out 0x3e, r19 ; write new stack pointer
  fe: 0f be        out 0x3f, r0  ; restore interrupt status

I don't see the other half of the stack pointer being written, though !!??

ajofscott

In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?

wh33t


In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?


Yes, that appears to be the case.

Nick Gammon


I don't see the other half of the stack pointer being written, though !!??


I left that line out:

Code: [Select]
  f8: 0f b6        in r0, 0x3f ; 63
  fa: f8 94        cli
  fc: 3e bf        out 0x3e, r19 ; 62
  fe: 0f be        out 0x3f, r0 ; 63
100: 2d bf        out 0x3d, r18 ; 61


I presume it's done in this order because the processor guarantees to execute one instruction after setting the interrupt flag, so the instruction at 0x100 is executed before an interrupt. Although I can't see exactly where it says that in the datasheet. It says after a SEI it executes the next instruction, that's not quite the same as saying "after enabling interrupts with the SREG register".
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon


In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?


Bear in mind these are local variables, not global ones. So you can't exactly do anything really useful with them (like, saving them from one function call to the next), and you can't destroy them as such.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

ajofscott

In the case of:
Code: [Select]

void foo(int newBound)
    {
      static char arrElements[];
      .....
    }

In other languages the static keyword keeps the scope variable arrElements persistent across calls to foo, and of course is only accessible within foo. Is this also apply in C? If so then I could simply return the pointer to arrElement[] to use it globally.

Go Up