C++ new & delete operator confusion

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've read several posts here about the missing new and delete operators and I'm still confused.

I put the definition of new and delete in my source code as suggested in another thread and it seems to work well.

If this is the case than why isn't it already in the GCC library? Should this be reported to the proper authorities? I realize the avr-libc FAQ says new and delete are not yet implemented. But if this is all it takes, maybe they should be told.

This is the actual quote from the FAQ:
The operators new and delete are not implemented, attempting to use them will cause the linker to complain about undefined external references. (This could perhaps be fixed.)

On the other hand if there is a problem with this implementation of the new and delete operators, I would like to know about it. It sure seems to work well for me.

Here is the code I added to my main.cpp:

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

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> If this is the case than why isn't it already in the GCC library?
> Should this be reported to the proper authorities? I realize the
> avr-libc FAQ says new and delete are not yet implemented. But if
> this is all it takes, maybe they should be told.

It's a workaround (others might call it a hack), not the real
implementation. The real implementation requires a C++ helper library
which isn't around there right now (and basically lacks a volunteer to
track all this down).

p.s.: Please don't use "Braille-sized letters" in your articles. It
makes you look rather dumb.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I've read several posts here about the missing new and delete operators

But this is not the only thing lacking in C++ for the AVR. Implementing them will not give you complete support for C++. And in fact those simple implementations of new and delete do not conform to C++ standards (for instance new should handle a size of 0 properly).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You may want to define the array handlers as well:

void* operator new[](unsigned int x);
void operator delete[](void *);

Dynamic memory allocation is considered problematic by many embedded developers so perhaps these implementations are left to those that are willing to take the risk.

While simply calling malloc/free seems all that is necessary, memory management can be much more complex, including memory compaction, out-of-memory reporting, multiple heaps, and garbage collection, just to name a few.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the replies. Those are good points. On the other hand for us C++ programmers, C seems problematic :D

I just do this as a hobby, and I've had good luck so far with C++, so I will stick with it. The alternative to new and delete that I had used was to construct classes on the stack. That worked but using new and delete makes for much nicer code.

I guess I would sum it up this way. There are no doubt good reasons not to use C++ for this microcontroller, but if you want to use it, as I do, then new and delete are the way to go.

As I see it, the reason to use C++ is that it produces code that is more modular, cleaner, easier to understand, and easier to re-use. When I didn't use new and delete, my code was messy and not much better than using C.

I should add that I do very little if any dynamic memory allocation. I construct everything at initialization and it stays there for the duration. On further thought, I do destroy my OSCCAL calibration thing after use.

Well, I would destroy all the classes at shutdown, if I could find the shutdown button :D I do use the reset button but I rather doubt all the destructors are being called. :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you've sort of missed the point. No one is saying not to implement new and delete, merely that they are not supplied because constructing robust implementations of them is problematic, especially given the wide range of resource capacity available through the AVR family. It is therefore easier/safer to let each individual create a new/delete to suit their particular needs.

Of course, if you want to create the library functions that address all the issues then good on you and good luck!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
As I see it, the reason to use C++ is that it produces code that is more modular....

You've veered into a new topic, that of C versus C++. You can search the archive as that issue has probably been beaten to death. The arguments for and against using new/delete should apply also to malloc/free.

I've seen C++ projects where new and delete were forbidden. All objects were created at global scope and so occupied heap space. (Stack would be used if the objects were declared within a function.)

Imagine what would happen if your code went crazy allocating and deallocating various size memory chunks. The heap can become fragmented and eventually the odds of new returning NULL are high. If you forget to free some memory, you've got a leak and ultimately you will probably experience a memory problem. And these problems can be a real pain to nail down.

Further, malloc/free are usually implemented with linked lists which require some memory overhead. If RAM is scarce this may be unacceptable.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> No one is saying not to implement new and delete, merely that they
> are not supplied because constructing robust implementations of them
> is problematic, [...]

No, that's not the reason. The C library offers implementations for
malloc() and free(), and they could (and would) effectively be used
for new and delete as well. The reason is simpy lack of a volunteer
who would track everything down that is needed for the C++ support
library, to a level where GCC could really be configured with an
option for a minimalistic C++ library (libsupc++).

As others have mentioned, the argument whether new and delete should
be used at all is the same as for malloc()/free(), and it boils down
to whether it is acceptable for your application to rely on
statistically ``unlikely to fail'' behaviour, or whether it needs to
be statically safe. Note that chaotic behaviour has proven to be of
great value, just think of Ethernet. Implementing similar
functionality in a statically safe way (Token Ring, to stick to
network protocols for a moment) usually takes up more resources, but
then, this is the price you have to pay for the guarantee of being
safe.

> All objects were created at global scope and so occupied heap space.

That's wrong. They occupy static memory. "heap" is the memory that
is used for dynamic memory allocation (malloc() or new).

> Further, malloc/free are usually implemented with linked lists which
> require some memory overhead. If RAM is scarce this may be
> unacceptable.

In avr-libc, free() is indeed using a linked list, but the malloc()ed
blocks itself are not. malloc() fully relies on the application
keeping track of their pointers, so the library doesn't have to also
remember them. The use of a linked list for the free list has the
only overhead that the minimal allocatable size of an object is 2, and
objects of size 1 are thus extended to be of size 2 (so each free()ed
memory object can then hold the link pointer). I think that's a
reasonable limitation which should have no noticable overhead in
practice.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
That's wrong. They occupy static memory. "heap" is the memory that
is used for dynamic memory allocation (malloc() or new).

Sorry, you are right. (As usual!)

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> In avr-libc, free() is indeed using a linked list, but the malloc()ed
> blocks itself are not. malloc() fully relies on the application
> keeping track of their pointers, so the library doesn't have to also
> remember them.

Minor correction (after thinking more about it): there is still another
2 bytes of overhead per block, yes. This is needed in order to keep
track of the allocation size of each memory block.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dl8dtl wrote:
> No one is saying not to implement new and delete, merely that they
> are not supplied because constructing robust implementations of them
> is problematic, [...]

No, that's not the reason. The C library offers implementations for
malloc() and free(), and they could (and would) effectively be used
for new and delete as well. The reason is simpy lack of a volunteer
who would track everything down that is needed for the C++ support
library, to a level where GCC could really be configured with an
option for a minimalistic C++ library (libsupc++).

As others have mentioned, the argument whether new and delete should
be used at all is the same as for malloc()/free(), and it boils down
to whether it is acceptable for your application to rely on
statistically ``unlikely to fail'' behaviour, or whether it needs to
be statically safe. Note that chaotic behaviour has proven to be of
great value, just think of Ethernet. Implementing similar
functionality in a statically safe way (Token Ring, to stick to
network protocols for a moment) usually takes up more resources, but
then, this is the price you have to pay for the guarantee of being
safe.

> All objects were created at global scope and so occupied heap space.

That's wrong. They occupy static memory. "heap" is the memory that
is used for dynamic memory allocation (malloc() or new).

> Further, malloc/free are usually implemented with linked lists which
> require some memory overhead. If RAM is scarce this may be
> unacceptable.

In avr-libc, free() is indeed using a linked list, but the malloc()ed
blocks itself are not. malloc() fully relies on the application
keeping track of their pointers, so the library doesn't have to also
remember them. The use of a linked list for the free list has the
only overhead that the minimal allocatable size of an object is 2, and
objects of size 1 are thus extended to be of size 2 (so each free()ed
memory object can then hold the link pointer). I think that's a
reasonable limitation which should have no noticable overhead in
practice.

Errr... I think "problematic" and "let each individual create a new/delete to suit their particular needs" pretty much sums up your rant?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No rants. As soon as someone volunteers to fix the current C++
issues, we'll be happy to ship new and delete out of the box, same
as we're shipping malloc() and free() in C.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.