RAM usage wrong when using pointers to class

I don’t understand how the RAM usage is estimated by the compiler. I made the following MCVE.
After compiling, the RAM usage shown by the Arduino compiler is wrong. I compared creating instances of the DataContainer struct in two ways, by having an array of pointers and call constructor using new (run time, heap? is that the correct name) and by just creating an array of the struct (compile time?).

#include <Arduino.h>

struct DataContainer {
    int values[100] = {0}; // init to zeros
    void FillRandom() {
        for (int k = 0; k < 100; k++)
            values[k] = random(0, 200);

class ExampleClass 
    DataContainer *data[20]; // Heap, runtime?
    // DataContainer data[20]; // or compile time

    ExampleClass() {
        for (int k = 0; k < 20; k++)
            data[k] = new DataContainer(); // not necessary when using: DataContainer data[20]

// declare class
ExampleClass EC;

void setup() {
    // call constructor
    EC = ExampleClass();
    EC.data[1]->FillRandom(); // for run time
    // EC.data[1].FillRandom();  // for compile time

If I compare the RAM usage that the compiler displays, I see the following.

Case 1, using DataContainer *data[20];

RAM:   [          ]   3.1% (used 63 bytes from 2048 bytes)
Flash: [=         ]   5.8% (used 1782 bytes from 30720 bytes)

Case 2, using DataContainer data[20];

RAM:   [==========]  195.9% (used 4013 bytes from 2048 bytes)
Flash: [          ]   3.9% (used 1194 bytes from 30720 bytes)

(I know that this is not gonna fit on the Arduino, just as an example).

Is there a way to still get an estimate of the RAM usage?

Is there a way to still get an estimate of the RAM usage?

How would you expect to estimate at compile time how many objects will be instantiated at run time?

Is there a way to still get an estimate of the RAM usage?

You answered your own question by declaring an array of DataContainer. If you declare an array of pointers to DataContainer and instantiate enough objects to populate the array of pointers you will use the amount of memory you saw in Case 2 plus the storage needed for 20 pointers.

Otherwise, the compiler has no idea how many times you will instantiate DataContainer.