Is it a good practice to free memory via a pointer-to-const

六眼飞鱼酱① 提交于 2019-12-05 01:38:45
mlvljr

Well, here's some relevant stuff possibly too long to fit into a comment:

  1. Some time ago the practice to free memory via a pointer-to-const was plain forbidden, see this dr. Dobb's article, the "Language Law" ( :)) part.

  2. There has twice been a relevant discussion on http://groups.google.ru/group/comp.lang.c++.moderated: "Delete a const pointer?", "Why can operator delete be called on a const pointer" (both actually deal with the case in question, i.e. pointer to const).

  3. My own point (since you are asking for arguments): possibility of the operation in question in any given context is defined by the (explicitly or implicitly defined in the documentation) contract of a class or a function, not by just the method signature or parameter types.

It is a good practice to use the proper strategy to end the lifetime of an object. For dynamic objects this means delete what you new, free what you malloc, and so forth. Whether that object is const or not has no affect on whether its lifetime should end.

Being constant or volatile are properties that exist within an object's lifetime, and that ends with a delete-expression or a call to free. Regardless of your own views on the matter or how things work in other languages, this is how C++'s object model works. A simple example to show this is how the language translates delete-expressions into operator delete calls:

#include <new>
void* operator new(std::size_t size);
void operator delete(void* p);

int main() {
  delete new int(); // int* to void*, since this is also an allowed
  // implicit conversion, it may not be clear what is happening

  // however, these are clearly not implicit conversions:
  delete new int const();          // int const         * to void*
  delete new int volatile();       // int       volatile* to void*
  delete new int const volatile(); // int const volatile* to void*
}

Another example, but perhaps less clear, is why you cannot overload ctors on const:

struct S {
  S() const; // not allowed
};

An object is only const after it is created (aka its lifetime begins; happens when the ctor returns normally) and before it is destroyed (aka its lifetime ends; happens as the dtor is entered). Before or after that lifetime you may have a pointer of type T const* (for example), but it does not point to an object and dereferencing it is UB.

The same line of reasoning applies to C, except you have to consider that C has roughly 40 years of history and has succeeded in maintaining a large amount of consistency for much of that time.

(I believe this question is subjective and argumentative and would vote to close it that way, except I apparently helped spark the discussion; so answering as CW.)

I've never really understood the arguments against deleting (or freeing) a const pointer. More precisely, I somewhat see the rational but it seems to me that they apply equally well to a const member in an object or a const variable in a bloc, and I've never see anybody argue that those should not be destroyed and their memory freed when the containing object is deleted or the execution leaves their containing block.

The two issues of managing the logical mutability of objects (i.e. const or not) and managing their life length (i.e. use an object variable, a smart pointer -- which and one -- or a raw pointer) seems unrelated to me.

In other words, if

{
    Foo const x;
    ...
}

is valid and good style. Why would

{
    Foo const* xptr = new Foo;
    ...
    delete xptr;
}

not be good style (using an adequate smart pointer instead of a raw one, but that is another issue).

Constness and lifetime are two different things. I see no problem freeing a const object if the owner of that object decides the object has no reason to live (the same way a const object that's a local will get 'deallocated' when it goes out of scope).

As far as free() not taking a const pointer, I think that one could argue either that that might have been an oversight of the standards committee or that that's because it takes the same kind if pointer that malloc() returns.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!