Creating Instances with NEW

It is likely, that this topic has still been handled in a forum thread, but I was not successful with searching ...

When I create an object from a class, there are two basic ways:

  1. Simply create the instance like any other variable:
    MyClass myInstance1;
  2. Creating a reference and using the new operator:
    MyClass *myInstanceRef1;
    ....
    myInstanceRef1 = new MyClass();

There are advantages using the 2. Method with NEW:
a.) You create the instance at run-time when needed and just delete it, if it is no more needed.
b.) You may use present parameters for the construction of Your object.
c.) Objects may be used with dynamic lists, etc.
d.) .... may be more

But using the 2. Method with NEW creates a code offset of about 60 kBytes (> 10% of Arduino Due).
I can imagine, that it takes code for a kind of memory allocation at run-time. But 60 kByte?
Does someone know the reason?
Do I make a mistake?

(I'm using Arduino 1.5.2 with Arduino Due.)

Post enough code to prove this point, please. Not just one line.

The code is very simple:

For both instantiation methods I will use the simple class MyClass:

class MyClass
{
  public:
    MyClass();                 // Default-Constructor
    MyClass(int initVal);      // Constructor with value
    void init(int initVal);    // init-Method for Default-Construction
    
    void run();                // Cyclic called method of MyClass
    
  private:
    int  runCounter;           // For doing something
};

MyClass::MyClass()
{
  runCounter = 0;
}

MyClass::MyClass(int initVal)
{
  runCounter = initVal;
}

void MyClass::init(int initVal)
{
  runCounter = initVal;
}

void MyClass::run()
{
  runCounter++;
}

The code above may be in an include-file or just written at the top of the test-sketch.

This is the test-sketch with direct instantiation:

MyClass  myInstance01;

void setup() 
{
  // put your setup code here, to run once:
  myInstance01.init(10);
}

void loop() 
{
  // put your main code here, to run repeatedly: 
  myInstance01.run();
}

It compiles to: Binary sketch size: 9.680 bytes (of a 524.288 byte maximum) - 1% used

Now this is the test-sketch with using the NEW operator:

MyClass  *myInstancePtr01;

void setup() 
{
  // put your setup code here, to run once:
  myInstancePtr01 = new MyClass(10);
}

void loop() 
{
  // put your main code here, to run repeatedly: 
  myInstancePtr01->run();
}

It compiles to: Binary sketch size: 69.920 bytes (of a 524.288 byte maximum) - 13% used

And it seems, that there is a big library included, if you use "new".
Though run-time memory allocation (as needed with new) may be rather tricky for limited memory, I cannot imagine a management which needs 60 kBytes of code.

Some info:
the new statement is defined in core arduino library new.h e new.cpp and use malloc() and free()
...\arduino-IDE\hardware\arduino\cores\arduino\

The new.h file include also stdlib.h

Thanks for Your info.
I now used sprintf additional to the direct instantiation. sprintf is a rather mighty C-function.
But the sketch size only grows from 9.680 bytes to 9.904 bytes.
So I assume, that the basic functions of stdlib (and stdio etc.) are contained in the first 9 kBytes of code.
I am now even more astonished about the 60 kBytes extra code with "new".

Kinda weird. I am using new in a sketch and it stays around the 8k or so normally compiled to. Freetronics Uno clone with 1.5.2 IDE.

Thank You for that hint.
I simply switched to Arduino Uno Board and the result was
Binary sketch size: 790 bytes (of a 32.256 byte maximum) - 2% used
And what is also strange, that the compilation time for Arduino Uno seems to be much shorter, than that for Arduino Due.
There may be something wrong with the Due environment.

The cores are linked in based on the board and its architecture, so it is possible there's something NQR with the library somewhere.

In a test case I had for Arduino Uno with the latest official release (1.0.5), the size difference is only 638 bytes in between allocating object from heap vs stack.

struct abc
{
  abc() {Serial.print(123);}
};

void setup() {}

void loop()
{
  abc x; // 1958 bytes
//  new abc(); // 2596 bytes
}

Using IDE 1.0.4, compiling for Uno:

Sketch with static allocation:

Binary sketch size: 542 bytes (of a 32,256 byte maximum)

Sketch with "new":

Binary sketch size: 790 bytes (of a 32,256 byte maximum)

Using IDE 1.5.2, compiling for Arduino Due (Native USB Port):

Sketch with static allocation:

Binary sketch size: 9,488 bytes (of a 524,288 byte maximum) - 1% used

Sketch with "new":

Binary sketch size: 60,776 bytes (of a 524,288 byte maximum) - 11% used

A lot more, yes.


However add these lines to the start of the sketch:

// new
void * operator new (size_t size) { return malloc (size); }
// placement new
void * operator new (size_t size, void * ptr) { return ptr; }
// delete
void operator delete (void * ptr) { free (ptr); }

Now it takes a lot less memory:

Binary sketch size: 11,296 bytes (of a 524,288 byte maximum) - 2% used

That's only (!) 1808 bytes more. There must be something strange in the way they have their linker options set up.

Reported here:

Thank You very much.
I'm deeply impressed by the culture of this forum and the high level of discussion.

As a teacher of the University of Applied Sciences and Arts in Hannover I started to introduce the Arduino environment to my students.
But we are engineers and try to optimize the usage of the boards concerning performance. Thus we started to create some new functions based on using references to the registers of SAM3X.
That is not depreciating the idea of Arduino to have compatible functions for all different boards, that is a great idea at all.
It is just opening the usage of Arduino Due for high speed state machines and other sophisticated software.

Thanks again and have a nice day.