Why delete can perform on pointers to const while free cannot?

前端 未结 4 910
鱼传尺愫
鱼传尺愫 2021-02-14 06:22

I\'ve just noticed that the pointers passed to delete can be const qualified while those passed to free cannot. That is really a surprise

相关标签:
4条回答
  • 2021-02-14 06:39

    free should not be used with actual C++ objects. free should be used with malloc, so you shouldn't be using free on something you allocated with new.

    As to why you can delete const objects, that's simple:

    const Type *ptr = new Type(...);
    

    Now what? If you couldn't delete that, then you'd have to do this:

    delete const_cast<Type*>(ptr);
    

    Having an object be const means that it cannot be modified. You cannot cause the object to go from one state to another state. Deletion is throwing it away. Meaning that it no longer exists in any state, whether the original one or some other modified form. Deletion is an operation that exists outside of the object's mutability state, much like construction.

    Conceptually, deletion is neither const nor non-const. While a destructor is a non-const function, the idea of destructing an object is simply outside the domain of const or non-const.


    OK, let's say you define operator delete to take a pointer to const (which is different from a const pointer):

    void operator delete(void const* p);
    

    What is the first line of this function going to be? The purpose of operator delete is to free memory that was allocated by operator new. That will require poking at bits on the memory allocation heap. And to do that, you need a pointer that does not point to const data:

    void *ptr = const_cast<void*>(p);
    

    Welcome to undefined behavior. While C++ allows you to do this, the specification is very clear that the results of attempting to write to ptr (or any address based on it) are undefined. You were given a const pointer; you were told by the outside world not to modify the stuff it pointed to. C++ provides no guarantees about what happens when you break that contract.

    Since the specification states that this is undefined behavior, and since operator delete (in most cases) cannot do its job without modifying the memory pointed to by p (or modifying memory based on that address), it would be silly of the specification to then allow you to define operator delete this way. It would basically be canonizing the idea of shooting yourself in the foot.

    Yes, in virtually every case, this would be completely safe. But since you're going to cast away the const anyway, why even bother to allow the rather dubious idea in the first place?

    0 讨论(0)
  • 2021-02-14 06:46

    One difference is that free is a library function and you must match the parameter type. When free was added to the C language there was no const keyword, so that couldn't even be considered.

    In C++ delete p is a statement handled by the compiler. It can do whatever the language designer wants it to, including not consider if the object pointed to is const or not.

    Philosophically speaking, the delete statement doesn't modify the object, it just makes it go away.

    0 讨论(0)
  • 2021-02-14 06:48

    The const modifier applied to a pointer means that the object pointed to will not be modified.

    However, delete takes the object permanently out of circulation. No one need care what happens to it after it is deleted. Hence for all we know, deletion might modify the object or it might not. Why does it matter? Any attempt to read or write the object's contents would be undefined behaviour.

    On the other hand, when you're implementing your own delete, you will likely need to modify the dying object. Hence the need for the pointer to be non-const.

    0 讨论(0)
  • 2021-02-14 07:00

    free is C function. Its signature is 20-30 years old, from times where there were no const in C language (and there was no C++ language as well). C++ compiler treats free like every other function, and can't let it accept const pointer without cast, because free could possibly change object pointed. Actually, it does, as well as delete, but C++ doesn't know that free is used for memory management.

    0 讨论(0)
提交回复
热议问题