Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
theusch
PostPosted: Feb 19, 2012 - 09:41 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25921
Location: Wisconsin USA

Quote:

NOTE: The worst case is still 320. We will never have more than 320 test points connected. Should the size of the array STILL be a fixed 320 elements?

I certainly would. Then you keep a count, set at startup probably, of the actual number this run.

Or you might have two or three types of data with various module types. Your AVR still has a fixed amount of SRAM that you'd be willing to devote to this before stack space gets squeezed. If this configuration holds for a run of this program, then make it a fixed buffer and cast pointers to the different areas. The overhead will still be less than handling a linked list of module data.
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Feb 19, 2012 - 11:40 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2651


NilRecurring wrote:
I had another question regarding arrays - what if it was necessary to determine the size of the array at runtime?
In that unlikely case, I'd use variable length arrays if possible.
The code is more obvious and the overhead is less.
Quote:
The 320 elements needed is for the worst case and when the system is actually running with 320 test points. The hardware of the circuit is such that the design is extendable via "daughter-cards". The main board, which has the uC, has 72 test points.

The number of daughter cards connected is controlled by a DIP switch and each daughter card will have 72 test points. In this case, it would be necessary to determine the size of the array at runtime, wouldn't it?
Not necessarily.
Quote:
NOTE: The worst case is still 320. We will never have more than 320 test points connected. Should the size of the array STILL be a fixed 320 elements?
Most likely.
Make it work.
Make it so you can tell it works.
Make it so other people can tell it works.
If it works with a fixed size array,
making it so you can tell it works favors the fixed size array.
Quote:
This extendable design is something we are considering and I thought I'd ask here what it would mean when it comes to arrays and memory.
In your worst case, every array will be its worst case.
The time to consider variable sized arrays is when that is not true, e.g.
you need 200 ints and 50 longs or 100 ints and 100 longs,
but not 200 ints and 100 longs.
If you have enough memory for 200 ints and 100 longs,
fixed arrays would still be a good idea.

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
lammelm
PostPosted: May 24, 2012 - 09:56 PM
Hangaround


Joined: Aug 27, 2007
Posts: 143
Location: Budapest, Hungary

JohanEkdahl wrote:

Well-well. I was convinced this was not allowed. You live and you learn.

The remaining warning then is that you should watch out so that you do not return (a pointer) to the array exiting the function where the variable was defined. At that point is is actually not "alive" any more, the memory it occupied is free for other uses and you might end up handling pure garbage later.

Example (sketchy, not tested):
Code:

int * foo(int theSize)
{
   int theArray[theSize];

   // Do something with theArray here...

   return theArray;  // DON'T DO THIS!
)


May I ask why wouldn't this code above work? By returning "theArray" pointer, the beginning address of the Array is provided to the caller, and the size of the Array is also known.

In an other thread this was posted by Clawson:

clawson wrote:

and then one that hasn't been proposed yet:
Code:
char * fillarray(void) {
  uint8_t i;
  static char staticarray[10];

  for (i=0; i<10 ; i++) {
    staticarray[i] = '0' + i;
  }
}

int main(void) {
  uint8_t i;
  char * data;

  data = fillarray();
  for(i=0; i<10; i++) {
    use(data[i]);
  }
}


I guess he missed the "return" part from the called function though.

His suggestion seem very much the same for me compared to what say we shouldn't do. Am I missing something?
Please enlighten me about this, because I'm learning these things right now.

thanks
 
 View user's profile Send private message  
Reply with quote Back to top
sternst
PostPosted: May 24, 2012 - 10:07 PM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2438
Location: Osnabrueck, Germany

Quote:
By returning "theArray" pointer, the beginning address of the Array is provided to the caller
But after exiting the function the array no longer exist, so the address of "nothing" is provided to the caller.

Quote:
His suggestion seem very much the same for me compared to what say we shouldn't do. Am I missing something?
Yes, you are missing the "static".

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: May 24, 2012 - 10:55 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18571
Location: Lund, Sweden

Quote:
May I ask why wouldn't this code above work?

Because the array variable is only valid as long as the function runs. As soon as the function exits that piece of memory may be used by something else. Every time the function is called a new instance of the local variable is allocated. This holds for variables that are not declared static.

For static local variables, it works in another way: Such variables are allocated once when the program starts, and no matter how many times the function is called all those instances of execution of the function will all access the same variable.

Example (sketchy, not actually compiled and run):

Code:
void foo(void)
{
   int anArray[10];
   anArray[7] = 42;
   return anArray;
}

void bar(void)
{
   int anotherArray[10];
   anotherArray[7] = 13;
   return anotherArray;
}

int main(void)
{
   int * aPointer;
   int * antherPointer;

   aPointer = foo();
   
   // At this point it is likely that aPointer[7] will evaluate to 42

   anotherPointer = bar();

   // At this point it is likely that aPointer[7] will evaluate to 13

   return 0;
}
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: May 25, 2012 - 09:25 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Am I missing something?

As others have said: "static" which means "leave this in memory so it can still be accessed even after this function exits". Without "static" the array is created on the stack on entry to the function and then destroyed/reused when it exits. If you return a pointer to it you are returning a pointer to somewhere in the stack that may now have other data or CALL/RET addresses in the middle.

While it might appear at the very moment of return that the data in the array is still there it would be EXTREMELY unwise to rely on this!

BTW returning pointers to automatics is one of the classic programming errors and while a C compiler probably won't spot such naughtiness a more aggressive checking tool such as lint or split should pick this up.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
lammelm
PostPosted: May 25, 2012 - 10:29 AM
Hangaround


Joined: Aug 27, 2007
Posts: 143
Location: Budapest, Hungary

JohanEkdahl wrote:
Quote:
May I ask why wouldn't this code above work?

Because the array variable is only valid as long as the function runs. As soon as the function exits that piece of memory may be used by something else. Every time the function is called a new instance of the local variable is allocated. This holds for variables that are not declared static.

For static local variables, it works in another way: Such variables are allocated once when the program starts, and no matter how many times the function is called all those instances of execution of the function will all access the same variable.

Example (sketchy, not actually compiled and run):

Code:
void foo(void)
{
   int anArray[10];
   anArray[7] = 42;
   return anArray;
}

void bar(void)
{
   int anotherArray[10];
   anotherArray[7] = 13;
   return anotherArray;
}

int main(void)
{
   int * aPointer;
   int * antherPointer;

   aPointer = foo();
   
   // At this point it is likely that aPointer[7] will evaluate to 42

   anotherPointer = bar();

   // At this point it is likely that aPointer[7] will evaluate to 13

   return 0;
}


But if you use static, and this function is in an other source file (for example an uart function in uart.c), then won't limit 'static' the scope of that variable to that source file?
 
 View user's profile Send private message  
Reply with quote Back to top
snigelen
PostPosted: May 25, 2012 - 10:43 AM
Posting Freak


Joined: Jan 08, 2009
Posts: 1155
Location: Lund, Sweden

You can't even access the variable outside the function it's defined in. But you can return a valid pointer to it that can be used anywhere.
 
 View user's profile Send private message  
Reply with quote Back to top
sternst
PostPosted: May 25, 2012 - 10:54 AM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2438
Location: Osnabrueck, Germany

lammelm wrote:
But if you use static, and this function is in an other source file (for example an uart function in uart.c), then won't limit 'static' the scope of that variable to that source file?
The scope of that variable is even limited to the function. But that has nothing to do with the "static" but with the fact that it is a local variable. "static" has two different meanings depending on whether it is a global or local variable (*). And "scope limiting" is only related to direct access to the variable (by its name). Access by a pointer is not affected by the scope.

(*):
"static" on global variable: scope limited to source file.
"static" on local variable: variable persists between calls of that function.

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: May 25, 2012 - 11:16 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18571
Location: Lund, Sweden

Do not mix up scope (visibility) and extent (lifetime).
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: May 25, 2012 - 12:24 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Do not mix up scope (visibility)

Also not that all rules about scope go out the window as soon as you starting handing pointers round Wink

Interesting recent thread on a similar subject (if you understand a bit about C++) here: http://www.avrfreaks.net/index.php?name ... p;t=120888

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits