通过指向const的指针释放内存是一个好习惯

时间:2010-02-18 11:45:19

标签: c++ c memory-management const-correctness

有很多问题讨论C和C ++处理指针到const删除的细节,即free()不接受它们,而deletedelete[]那样做constness不会阻止对象的破坏。

我感兴趣的是你是否认为这样做是一种好习惯,而不是语言(C和C ++)允许的。

指针到const删除的参数包括:

  • Linus Torvalds'kfree()与C free()不同,它采用void const*参数,因为他认为释放内存不会影响指向的内容。
  • free()是在引入const关键字之前设计的。
  • C ++的删除操作符允许删除const数据。

反对它的论据包括:

  • 程序员在向指针传递指针时不希望修改(或删除)数据。
  • 许多人认为指针指向const意味着没有获得数据的所有权(但非const意味着获得所有权)。
  • 这是大多数库和现有代码中常见的做法。

请在您的回复中充分说明,并可能参考当局。我的意图不是在这里开始投票。

4 个答案:

答案 0 :(得分:4)

使用正确的策略来结束对象的生命周期是一种很好的做法。对于动态对象,这意味着删除你的新内容,释放malloc,等等。该对象是否为const对其生命周期是否应该结束没有影响。

常量或易失性是对象生命周期中存在的属性,以delete-expression或free对空调的结束。无论您对此事的看法如何,或者其他语言的工作原理如何,这都是C ++的对象模型的工作原理。显示此问题的一个简单示例是语言如何将delete-expressions转换为运算符删除调用:

#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*
}

另一个例子,但也许不太清楚,为什么你不能在const上重载ctors:

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

一个对象在创建之后只是const(也就是它的生命周期开始;当ctor正常返回时发生)并且在它被销毁之前(也就是它的生命周期结束;在输入dtor时发生)。在该生命周期之前或之后,您可能有一个类型为T const*的指针(例如),但它不指向一个对象,并且取消引用它是UB。

同样的推理也适用于C,除非您必须考虑C已有大约40年的历史,并且在大部分时间内成功地保持了大量的一致性。

(我相信这个问题是主观的和争论性的并会投票以这种方式关闭它,除了我显然帮助spark讨论;所以回答CW。)

答案 1 :(得分:3)

我从未真正理解反对删除(或释放)const指针的论点。更确切地说,我有点看到理性,但在我看来,它们同样适用于对象中的const成员或集团中的const变量,我从未见过任何人认为那些不应该被破坏和他们的记忆删除包含对象或执行离开其包含块时释放。

管理对象的逻辑可变性(即const或不是)和管理它们的生命周期的两个问题(即使用对象变量,智能指针 - 哪个和一个 - 或原始指针)似乎与我无关

换句话说,如果

{
    Foo const x;
    ...
}

是有效且好的风格。为什么会

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

不是好风格(使用足够的智能指针代替原始指针,但这是另一个问题)。

答案 2 :(得分:2)

嗯,这里有一些相关的东西可能太长,不适合评论:

  1. 前段时间通过指向const的指针释放内存的做法是明确禁止的,请参阅this dr. Dobb's article, the "Language Law" ( :)) part

  2. 有两次关于http://groups.google.ru/group/comp.lang.c++.moderated的相关讨论:"Delete a const pointer?""Why can operator delete be called on a const pointer"(两者实际上都涉及有关案例,即指向const的指针)。

  3. 我自己的观点(因为你要求参数):在任何给定的上下文中有问题的操作的可能性是由类(或文档中的显式或隐式定义)的类或函数的契约定义的,而不是仅通过方法签名或参数类型。

答案 3 :(得分:0)

Constness和life是两回事。如果该对象的所有者决定该对象没有理由存活,我认为释放一个const对象没有问题(当一个本地的const对象超出范围时会被“解除分配”的方式相同)。 / p>

至于free()没有采用const指针,我认为可能会争辩说这可能是对标准委员会的监督,或者那是因为如果指针采用相同的类型malloc()返回。