Dynamic memory allocation with 'new' operator

Is it a good idea to dynamically allocate memory in Arduino with the C++ 'new' operator, and clean up with 'delete'? Or with malloc() and free() for that matter. I just mean dynamic memory allocation in general really.

I would never have thought I'd be asking this question 10 years ago, with respect to micro-controllers, but things have come a long way.

I realise that care would need to be taken not to exceed the available space, but was wondering about other potential pitfalls.

Have you got a problem that you are trying to overcome ? Shortage of memory, perhaps ?

I suspect that you will find that with most Arduinos it is preferable to make best use of the memory that you have by using the F() macro and PROGMEM, for instance, rather than messing around with allocating/deallocating it.

UKHeliBob:
Have you got a problem that you are trying to overcome ? Shortage of memory, perhaps ?

I suspect that you will find that with most Arduinos it is preferable to make best use of the memory that you have by using the F() macro and PROGMEM, for instance, rather than messing around with allocating/deallocating it.

No problem right now, Bob, and I may never need to. Just asking for reference. I thought that if dealing with large amounts of storage and, I guess, if the code space is pretty full, it could be very handy to be able to re-use memory in this way.

And I haven't heard of the F() macro. Edit: I just did some reading on it.

Apart from reserving a chunk of memory, malloc and new essentially do different things (One is how C does dynamic allocations, and the other is the C++ way).

Here is some articles I wrote a while ago:

http://arduino.land/FAQ/content/4/26/en/how-to-use-dynamic-memory.html
http://arduino.land/FAQ/content/4/24/en/mixing-malloc-and-new.html

pYro_65:
Apart from reserving a chunk of memory, malloc and new essentially do different things (One is how C does dynamic allocations, and the other is the C++ way).

Here is some articles I wrote a while ago:

http://arduino.land/FAQ/content/4/26/en/how-to-use-dynamic-memory.html
http://arduino.land/FAQ/content/4/24/en/mixing-malloc-and-new.html

I actually thought they did much the same thing. I'll read your articles in a moment.
And PROGMEM is only useful for constants, for storage during compilation, isn't it?
I'm just beginning, and trying to get everything clear in my head. I've never even used PROGMEM yet.

Edit: And I should add, I only added malloc() as an afterthought - I'd only ever use new / delete. I'm more familiar with C++ than C.

OldSteve:
I actually thought they did much the same thing.

And you were/are right.
Have a Look at the Arduino implementation of new and delete

void *operator new(size_t size) {
  return malloc(size);
}

void *operator new[](size_t size) {
  return malloc(size);
}

void operator delete(void * ptr) {
  free(ptr);
}

void operator delete[](void * ptr) {
  free(ptr);
}

Whandall:
And you were/are right.
Have a Look at the Arduino implementation of new and delete

void *operator new(size_t size) {

return malloc(size);
}

void *operator new[](size_t size) {
  return malloc(size);
}

void operator delete(void * ptr) {
  free(ptr);
}

void operator delete[](void * ptr) {
  free(ptr);
}

Thanks for that Whandall. You've definitely made that clear. :slight_smile:
So I get the idea that basically there's nothing wrong with dynamic memory allocation if the situation calls for it then.
As mentioned, I may never need to, but it's good to know what should and shouldn't be done.
In PC programming, I've always liked being able to decide at runtime just how big an array should be. Very handy.

I'll have to read up on PROGMEM too. I got a little confused before, but I think it and F() are only useful for compile-time constants aren't they, or can PROGMEM be used to write to program flash memory at runtime?

Attention to the finer details always prevails, I already mentioned they both allocate memory:

Apart from reserving a chunk of memory, malloc and new essentially do different things

One gives you nothing more than a block of memory. The other can fully construct and initialize an object...

Very different to those that know!

(Whandall's code snippet really shows nothing of what happens in the background, just where the allocation comes from.)

pYro_65:
Attention to the finer details always prevails, I already mentioned they both allocate memory:

One gives you nothing more than a block of memory. The other can fully construct and initialize an object...

Very different to those that know!

(Whandall's code snippet really shows nothing of what happens in the background)

I can't see how anything else could happen in the background if new merely calls malloc() and delete simply calls free(). There is no call to any other function within those definitions.

As mentioned, I wouldn't use malloc() anyway, but am getting confused by the conflicting advice.

And is your 'placement new' article still on the way?

Edit: It is obvious that if those definitions are correct, which I have no reason to doubt, then delete will not call the destructor for objects, and therefore won't clean up properly, but if those are the definitions then that is the case, and only non-object-oriented variables should be declared dynamically in arduino. Normal variables and arrays would be cleaned up properly though.

new and delete are operators, there are things in the background which occur automatically. The code inside the functions return a pointer where C++ will construct the object after returning (using new is significantly different to a simple malloc() call also).

The second article I linked mentions this also.

Here is an example where you can see this happening, and remove any doubt:

struct blink{

  blink(){ 
     pinMode(13, OUTPUT);
     digitalWrite(13, HIGH);
  }

  ~blink(){ 
     digitalWrite(13, LOW);
  }
};


void setup() {}

void loop() {
  blink *b = new blink;

  delay(1000);

  delete b;

  delay(1000);
}

pYro_65:
new and delete are operators, there are things in the background which occur automatically. The code inside the functions return a pointer where C++ will construct the object after returning (using new is significantly different to a simple malloc() call also).

The second article I linked mentions this also.

Here is an example where you can see this happening, and remove any doubt:

struct blink{

blink(){
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
  }

~blink(){
    digitalWrite(13, LOW);
  }
};

void setup() {}

void loop() {
  blink *b = new blink;

delay(1000);

delete b;

delay(1000);
}

Excellent - that's a good way to confirm it. Thank you for that. I hadn't got far enough to consider writing a class or struct to test it.

I know that the constructor and destructor 'should' be called, but couldn't see how that would happen from the definitions shown.
I still can't, but will just be happy if I know that OOP objects are correctly created and destroyed if I use new.

Edit: And they are - the LED is blinking happily. On with the constructor and off with the destructor.

Thank you both for your help, and HeliBob too, for your input. I'll leave here tonight happy to use new and delete for dynamic memory allocation. That's all I wanted.

The question was 'Dynamic memory allocation with 'new' operator'.

In respect to memory allocation there is no difference (in the arduino implementation).

New calls the constructor of the new object(s), that's the way C++ works,
but in respekt to the question asked, that obvious fact is irrelevant.

Whandall:
The question was 'Dynamic memory allocation with 'new' operator'.

In respect to memory allocation there is no difference (in the arduino implementation).

New calls the constructor of the new object(s), that's the way C++ works,
but in respekt to the question asked, that obvious fact is irrelevant.

Yeah, that's all I was really concerned with when I wrote the title - potential problems using new. I only added malloc() as an afterthought as I wrote the actual post.

I just got a little confused when I read those definitions since they didn't appear to do anything about constructors and destructors. I still don't understand the mechanism that actually calls the constructor and destructor, but I don't care too much about that, I'm just happy that it happens. :slight_smile:

Anyway, my question has been pretty well answered. I haven't been presented with any reasons not to use dynamic memory allocation.

Thanks again.

OldSteve:
any reasons not to use dynamic memory allocation.

  • there is an overhead
  • you have the problem of fragmentation
  • its very easy to do things wrong (like not checking for NULL)
  • you have not enough memory to really make use of dynamic objects
    If you know what you do, go ahead.

Under normal circumstances you do not really have to use malloc/new (or String ;)).

That is really a very biased view.

there is an overhead

Of two bytes per allocation, not really much, even for an Arduino. The actual allocation time for a block from the malloc call can be variable. If part of your app is time critical, you simply do it at an appropriate time.

you have the problem of fragmentation

This is really the only major problem, which is easily mitigated by good design.

its very easy to do things wrong (like not checking for NULL)

Not unlike forgetting to call x.begin(), or anything else for that matter! However unless you are re-using the same pointer, you'll never have to do this.

you have not enough memory to really make use of dynamic objects

You have access to the same amount of memory you'd otherwise use for global/local variables.

I agree most applications will not need it, however it is just another option on the table.

pYro_65:
That is really a very biased view.

there is an overhead

Of two bytes per allocation, not really much, even for an Arduino. The actual allocation time for a block from the malloc call can be variable. If part of your app is time critical, you simply do it at an appropriate time.

you have the problem of fragmentation

This is really the only major problem, which is easily mitigated by good design.

its very easy to do things wrong (like not checking for NULL)

Not unlike forgetting to call x.begin(), or anything else for that matter! However unless you are re-using the same pointer, you'll never have to do this.

you have not enough memory to really make use of dynamic objects

You have access to the same amount of memory you'd otherwise use for global/local variables.

I agree most applications will not need it, however it is just another option on the table.

Fragmentation is obviously the biggest potential problem. I'll have to keep that in mind. There's no fancy memory management in Arduino as far as I'm aware.

Regarding having enough available memory, I'd only ever do it if I knew the upper limit of the memory I'm likely to allocate dynamically. And of course, the amount of free memory after compilation.

It's another good tool in the toolbox, the way I see it. And I'd only use it under exceptional circumstances as mentioned earlier.

It has it's pitfalls, and has to be used with care, as is the case with dynamic memory allocation in a PC.

Thank you both again for your advice and input. I'll go away now, read those articles properly, and digest what I've been told.

Hi, i know this topic has been idle for over a year, but just in case someone is still listening...
I actually have a use case for dinamically allocated memory which seems to be quite reasonable, even though it doesnt involve lots of memory, that is, when you can only determine the required amount of memory at run time, for example for allocating a few small arrays of different sizes and the sizes need to be determined by the user.
I imegine i can di this safely as long as i keep track of memory limits, right.

the sizes need to be determined by the user.

What's the maximum the user is allowed to pick? There is a max, right?

Just use that max for a static declaration and save yourself some program space by not including the malloc routines. After all, these are "just a few small arrays".

Cheers,
/dev

The links are dead, any new links?

pYro_65:
Apart from reserving a chunk of memory, malloc and new essentially do different things (One is how C does dynamic allocations, and the other is the C++ way).

Here is some articles I wrote a while ago:

http://arduino.land/FAQ/content/4/26/en/how-to-use-dynamic-memory.html
http://arduino.land/FAQ/content/4/24/en/mixing-malloc-and-new.html

bieboebap:
The links are dead, any new links?

Works for me.