Class code and where it goes

Hi,

I was wondering about where code and data gets put in memory using c/c++ with regards to Arduino? Below are some examples with questions:

class test
{
   test() {}
  ~test() {}
  void foo() {int a=0;}
};

setup() {}
loop()
{
  test t = test();
  t.foo();
}

So, where is the code above… is it in the normal flash memory? Would the ‘int a’ in foo() be in SRAM no matter what? And am I right in saying that if you did this:

#include <stdlib.h> 
void* operator new(size_t size) { return malloc(size); }
void operator delete(void* ptr) { free(ptr); }

loop()
{
  test *t = new test();
  t->foo();
}

…that there would be an instance of test in SRAM?

Also, like I asked before… where would the ‘int a’ in foo() be as well?

Many thanks in advance for helping me sort this out in my head!

Phil

Based on what little I know about the ATMega and its memory layout, I would have to say that both are in SRAM. But before you take that as gospel, maybe someone with more knowledge on this than me should chime in...

:slight_smile:

On the avr processors, ALL code is in flash, you cannot execute instructions from RAM.

The arduino environment does not allow "new" nor delete.

You have to declare it statically. Also your initializer function cannot do much, in fact it should really not do anything. You would then need a method called init and from setup up, you would do "t.init();"

The memory for the instance of the class would be in RAM and therefore "a" would also be in ram.

Can you get around the lake of "new" and "delete" the answer is yes, there are some posts around here someplace describing how to do it or you can use something like eclipse. I dont recommend it because of the sever RAM limitations.

I hope this helps.

Mark

test t;

setup()
{
   t.init();
}

loop()
{

}

Hi,

Thanks for the replies. I think i've seen something before about declaring new and delete operators (in fact I put it in some example code in my original post). After some experimentation I have found that I can use C++ code which also uses the constructor to init some other things associated with that object.

The classes i'm using are light weight enough that I can get away with creating instances with the above new and delete operators and not wipe out all of the RAM - in fact i'm left with 1.2k free out of 2k.

What i've opted for is to have a static class or at least a class that is not instanciated, with the main code for the process and to have another class with any dynamically changing variables (I suppose this could probably be a struct though). It's the second class that is instanciated and put into SRAM. Since this contains no code, just data (and only the data that is going to change) it seems to cut back on the memory used. There is also the slight overhead of having to keep a list of object pointers.

Also, i've changed the above new and delete to account for all memory used, so I can handle memory better.

What i've found is that C++ (excluding the fact that you have to define new and delete manually) can be compiled exactly the same as code intended for linux or any other system. The only difference is that there is less memory and you have to think about the hardware more (what I mean by that is communicate with it directly rather than through an operating system using system calls etc - although I understand that you can do it directly if you wanted to. Just that on avr there is no real option for that... anyway). What's brought me to this conclusion is that i've got a program I made specifically for the PC using Cygwin, and the only thing I changed is printf to serial.println to get the output. The way it creates objects from classes, the way it initializes through the constructors etc is the same. This code inherits and uses virtual, all work fine.

It seems the only difference is that the new and delete operators aren't defined. This also answers another question I had which asked if the compiler used is restricted in any way or are there things you cannot do. It seems that there aren't many restrictions at all.

I agree that it's not the best thing to do considering the limitations. But it does have the advantage of keeping the state via objects in memory for multiple things. It seems easier to do this via C++ rather than write extra code in C to manage it manually. In fact, this is something I haven't tried - so you may not need any code... it may just be the readability that is easier to understand to me.

Anyway, sorry for the essay. I'd like to hear other peoples opinions about this.

Thanks,

Phil

Also...

I've just realised that the only reason you need the setup() and loop() is because it's called from main() in the base hardware code. I've seen something in a project called Pyrix (I think) where they define another hardware type and from what I see you could essentially disregard the setup() and loop() and get it to call functions closer to your lifecycle from within your own main().

I've not tried this so don't know if you will encounter problems further down, like when you try to build it if there are any errors because of this. From what I can see the only reason you call the current loop() is because in main() it is in an infinate loop, which mean if you took this away the code would only ever run once. You would have to keep reseting the device to re-run.

Anyway, guess i'm thinking out loud and trying to explore the possibilities of this great hardware/software package.

...if you've read this far, thanks for taking the time :slight_smile: