4

I am curious how the delete operator know the size of the derived class when calling delete on base pointer, here is a minimal example:

class IVariant
{
public:
    virtual ~IVariant() = default;
    virtual void print_value() = 0;
};

template<typename T>
class Variant: public IVariant {};

template<>
class Variant<int>: public IVariant
{
private:
    int m_integer;

public:
    Variant(int integer): m_integer(integer) {}
    void print_value() override
    {
        printf("integer: %i\n", m_integer);
    }
};

template<>
class Variant<double>: public IVariant
{
private:
    double m_dbl;

public:
    Variant(double val): m_dbl(val) {}
    void print_value() override
    {
        printf("double: %g\n", m_dbl);
    }
};

template<>
class Variant<std::string>: public IVariant
{
private:
    std::string m_string;

public:
    Variant(const std::string& string): m_string(string) {}
    void print_value() override
    {
        printf("string: %s\n", m_string.c_str());
    }
};

Test:

int main()
{
    IVariant* int_var = new Variant<int>(100);
    IVariant* dbl_var = new Variant<double>(100.0f);
    IVariant* str_var = new Variant<std::string>("the value is 100\n");

    int_var->print_value();
    dbl_var->print_value();
    str_var->print_value();

    delete int_var;
    delete dbl_var;
    delete str_var;
}

The delete operator correctly knew from the base pointer alone that int_var = variant<int> so freed 4 bytes, dbl_var = variant<double> so freed 8 bytes, str_var = variant<std::string> so it freed 28 bytes.

But how does it know? Does the new operator store size & pointer which the delete operator can then use to free the correct number of bytes? I know this is how delete[] works for arrays but I was unable to find any info when it came to derived classes

6
  • This is implementation defined. You will need to specify which implementation you want to know about for a meaningful answer. Commented Feb 16, 2017 at 20:37
  • In short, yes. The heap allocation has size and type information for each object that has been created. Calling delete will go to the lookup table and free the respective amount of bytes for the given object. Commented Feb 16, 2017 at 20:40
  • 2
    The default heap memory allocator of your standard library's operator new "knows" how much memory is owned by each pointer it handed out to you. Its the one responsible for the cleanup, of cause after the runtime has correctly called the appropriate destructor. Commented Feb 16, 2017 at 20:40
  • @callyalater "size and type information" - what type information does the heap allocator have? Commented Feb 16, 2017 at 20:40
  • @NirFriedman Some implementations will store template type sizes (which is what I meant by type information) when used in a typedef, using, or member variable context to determine what offsets to use and to provide type checking at runtime. But, the type information (if any) is implementation defined. Commented Feb 16, 2017 at 20:43

1 Answer 1

10

delete and delete[] operators know the size of the allocation, because operators new and new[] save some housekeeping information for them at the time of allocation. It uses the same idea as malloc/free pair, when malloc saves size information that is required for free to do its job.

Figuring out the allocation size is independent of the type for which the memory is allocated. Operators delete and delete[] do not even know the type of the pointer being deleted, because they operate on void pointers.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.