Go Down

Topic: Declaration of a Dynamic Array of Objects (Read 13228 times) previous topic - next topic

Groove

#15
Jul 28, 2010, 04:42 pm Last Edit: Jul 28, 2010, 04:44 pm by GrooveFlotilla Reason: 1
@InvalidApple:
I think you're misunderstanding the difference between a class (or object) and a struct.

As PaulS pointed out, malloc'ing some memory and casting the pointer to it does not a class instantiate.
If you doubt me, try calling one of the class methods.
Per Arduino ad Astra

PaulS

@Groove
That's the thing we are having the discussion about. He says that he did run the sketch, which does call the instance's methods, and that it worked.

I'm having a hard time accepting that.

I'm going to try it at home, tonight.

wonginator1221

#17
Jul 28, 2010, 06:04 pm Last Edit: Jul 28, 2010, 06:07 pm by wonginator1221 Reason: 1
15 posts in 24 hours!  Thanks for all the help.

Personally, I have a Java background, but I'm pretty familiar with C's malloc.  

I initially avoided malloc because many C++ "tutorials" suggest staying away from malloc as it is often a source for memory leaks.  However, if it's the only way to truly dynamically allocate memory, it shouldn't be an issue.

After digesting InvalidApple's code and the responses generated I have concluded that malloc must call the default constructor for MyClass (without the int parameter).

Code: [Select]

#define ROWS 3
class MyClass {
 int _var;
 public:
   MyClass() {
     _var = 0;
   };
   MyClass(int a) {
     _var = a;
   };
   void setVar(int a) {
     _var = a;
   }
   int getVar() {
     return _var;
   };
};

MyClass *arr;
void setup() {
 Serial.begin(9600);
 arr = (MyClass *) malloc(sizeof(MyClass) * ROWS);
 for(int i = 0; i < ROWS; i++)
   arr[i].setVar(i + 1);
 
 for(int i = 0; i < ROWS; i++)
   Serial.print(arr[i].getVar());
   //Should return '1 2 3'
}

void loop() {}


Currently I don't have an Arduino to test this on, but I'm pretty sure this works.  Multidimensional arrays would just require more 'for' loops.

Now for the real question:
Are objects extremely memory intensive (for an Arduino)?  I've created a simple pixel class that lets me easily set the color of an RGB LED and I plan to create up to 64 of these 'Pixel' objects.  Are there more efficient structures for this type of application?

Thanks again!


PaulS

Quote
Are objects extremely memory intensive (for an Arduino)?

That depends on haw many, and what type of, fields and methods the class has.

Quote
I have concluded that malloc must call the default constructor for MyClass

The malloc function does not call the constructor. There may, or may not be some other mechanism that does.

I want to dump the assembler code that is generated, and see what it shows.

Coding Badly

Quote
The code works.  I made sure before I posted it.

Your testing is far from complete.

Add and call several virtual functions and please let us know what happens.

InvalidApple

The only thing that I said is that the code works.  I stand by that, because I tested it before posting it.  

Also, I got "123" on my screen when I ran wonginator1221's code.  If it works, it works.

@Groove: In C++, the only difference between struct and class is the default public/private. (Schildt, H. (2003), 'C++: The Complete Reference, Forth Edition', "Structures and Classes Are Related", page 293, McGraw Hill/Osborne, California)

And for the love of god, please try it before posting anything about it.

[code]struct myClass {
 int i;
public:
 void init(int I) {
   i = I;
 }
 int show() {
   return i;
 }
};


void setup() {

 myClass *p[16];

 Serial.begin(9600);

 for(uint16_t i = 0; i <= 5; i++) {
   p = (myClass *) malloc(sizeof(myClass));
 }

 p[0]->init(0);

 p[2]->init(8);

 p[6]->init(7);

 Serial.println(p[0]->show());

 Serial.println(p[2]->show());

 Serial.println(p[6]->show());

}

void loop() {

}

[\code]

When I tried it, I got:
0
8
7

... on the serial monitor.

Quote
Your testing is far from complete.

No.  I just made a quick program to help someone that worked.  If you want to explore the matter further, you are more than welcome to.

Coding Badly

Quote
I just made a quick program to help someone that worked.

I apologize.  My post comes across as very sarcastic.  That wasn't my intent.

Quote
If you want to explore the matter further, you are more than welcome to.

There's no need for me to explore the matter.  I know for a fact that new performs serveral things not performed by malloc.  I also know free is not a replacement for delete.  I suspect you also know those things.

Please bear in mind that people who are writing their very first Arduino Sketch come here searching for help.  When they find this thread, without a word of caution, they will believe that malloc can always be used in place of new.

BenF

Quote
When they find this thread, without a word of caution, they will believe that malloc can always be used in place of new.

I fully agree with this, but would add to it. NEVER use malloc or any of its derivatives in your projects.

There is only a single pool of RAM memory and there is just not enough of it to make this a viable approach on 8-bit AVR's such as the AtMega328. Although more than useful on other platforms (such as Windows, Mac, Unix) it is asking for trouble on Arduino's. When frequently allocating/freeing memory with global references, you run the risk of fragmented memory and soon "disaster" strikes when stack and/or other memory is overwritten. It is very difficult at best to predict and guard against such errors when writing software and even worse to debug when issues materialize. This is also a major source of errors on platforms where memory is available in abundance (memory leaks accumulating over time).

It may be educational to explore the finer arts of dynamic C++ classes, but Arduino is not the right platform for this. I would also stay clear of any Arduino library that make use of dynamic memory.

wonginator1221

So from my understanding of the situation:

  • malloc can create objects even though it technically shouldn't
  • Don't use malloc


  • The 'new' keyword should be used in place of malloc
  • 'new' does not exist


My understanding of the situation:

Quote

Q: How do I dynamically allocate memory?

A: Don't



AWOL

I don't claim to be a C++ luminary, but the malloc method (I think) doesn't/can't call the object's constructor, even a default one.
Use the "malloc" method if that's the only way you can do what you wish, but be aware of its limitations and pitfalls.

Generally don't use malloc on a microcontroller if you can (and you usually can) avoid it - it carries with it usually unacceptable memory usage overheads.
"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.

Coding Badly

Quote
malloc can create objects even though it technically shouldn't

malloc does not create objects.  It allocates memory from the heap and nothing more.  InvalidApple provided an example where "creating an object" is a simple enough operation that it is possible to overcome the difference.

Quote
Don't use malloc

On microcontrollers, there are dangers and limitions with malloc.  If you feel you understand the pitfalls and you truly need dynamic allocation then malloc is a reasonable choice.

Go Up