Pages: 1 [2]   Go Down
Author Topic: Declaration of a Dynamic Array of Objects  (Read 11823 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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.
« Last Edit: July 28, 2010, 09:44:02 am by GrooveFlotilla » Logged

Per Arduino ad Astra

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 614
Posts: 49384
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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!

« Last Edit: July 28, 2010, 11:07:16 am by wonginator1221 » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 614
Posts: 49384
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 208
Posts: 12931
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Melbourne, Australia
Offline Offline
Full Member
***
Karma: 0
Posts: 219
Have you tried turning it off and on again?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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(smiley-cool;

  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.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 208
Posts: 12931
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26331
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"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.

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 208
Posts: 12931
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: 1 [2]   Go Up
Jump to: