【问题标题】:C++ Dynamic Memory Best PracticeC++ 动态内存最佳实践
【发布时间】:2018-03-09 16:03:43
【问题描述】:

我正在学习 C++,我遇到了一些代码,我对它到底做了什么感到困惑。我正在学习动态记忆,我学习它的地方提到这是一个很好的做法。

double * pvalue = NULL;

if(!(pvalue = new double)){
  cout<<"Error: out of memory." << endl;
  exit(1);
}

我知道您正在创建一个名为 pvalue 的指针,但我不明白 if 语句。如果有人可以向我解释,我将不胜感激。

【问题讨论】:

  • 请编辑您的代码!
  • new 永远不会返回 nullptr,除非您提供 std::nothrow
  • new 几乎从来都不是“好习惯”。
  • 你可能会发现这很有用stackoverflow.com/questions/26419786/…
  • 为什么不使用new?因为程序员现在负责管理分配的内存,并且许多计算机程序已经死去可怕的死亡,因为他们的程序员错误地认为他们管理了他们的内存。令人惊讶的是它有多么棘手。使用偏好的一般顺序类似于:自动分配、library containersmart pointernewnew 下面有东西,但现在最好不要管它。

标签: c++


【解决方案1】:

我对它到底做了什么感到困惑。

使用非常过时的概念和对 C++ 的有限理解。

首先,C++ 不会通过返回NULL 来报告分配内存失败。它会抛出 std::bad_alloc 类型的异常(从 std::exception 派生)。

其次,随着 C++11 的出现,使用像这样的“裸”指针是不受欢迎的,因为当你忘记 delete 它们时,它们很容易导致资源泄漏,例如当意外异常使您的指针超出范围时。

所以你真的应该使用std::shared_ptr<>unique_ptr<>

【讨论】:

  • 可以说比潜在泄漏更糟糕的是在使用原始指针时出现悬空指针的机会。使用智能指针,您可以确保指针对象的可见性和生命周期匹配,因此您不会意外取消引用指向不再存在的对象的指针。
【解决方案2】:
     pvalue = new double   // This allocates a dynamic double as usual
   !(pvalue = new double)  // This takes the value of the resulting pointer
                           // and negates it, checking whether it's null
if(!(pvalue = new double)) // It all becomes the condition for the if.

值得注意的是:

  • 在 C++ 中必须使用原始拥有指针,而应使用智能指针;
  • 不得使用using namespace std;(我确定此示例具有);
  • 动态分配单个double奇怪的
  • 普通的new从不返回一个空指针,所以检查是没有意义的;
  • std::exit 将在你的程序运行中对你的程序进行核攻击,泄漏所有具有自动生命周期的对象,而是从 main 返回。

[...] 我学习它的地方提到这是一个很好的做法。

是时候戴上一些重金属和太阳镜,放火烧“那个地方”,然后去找一些更好的学习材料。

【讨论】:

  • @ChristopherReif 恐怕我没有最好的情报,但我们有经常链接的a curated list of good C++ books。我自己在 StackOverflow 上阅读问答时发现了很大的学习价值。
【解决方案3】:

这个:

if(!(pvalue = new double)){

... 只是一种(也许也是)聪明的速记方式:

pvalue = new double;
if (pvalue == NULL) {...}

【讨论】:

  • ...反正也没有意义。
  • 是的,当然,这确实回答了所提出的问题。但没有指出,检查在 C++ 中毫无意义确实是严重疏忽。此外,未能解释为什么if(!some_pointer) 具有与if(some_pointer == nullptr) 相同的效果(通常)也有点令人不满意。恐怕,我需要对这个提交投反对票,因为它真的没有用。
【解决方案4】:

new 永远不会返回 nullptr,除非您提供 std::nothrow。相反,如果 new 失败,它将抛出 std::bad_alloc

更合适的解决方案是:

#include <iostream>
#include <stdexcept>

double * foo()
{
    double * pvalue = nullptr;

    try {
        pvalue = new double;
    }
    catch(const std::bad_alloc &)   {
        std::cout << "Error: out of memory." << std::endl;
        exit(1);
    }
    return pvalue;
}

但是,在现代代码中不鼓励使用原始的拥有指针。通常避免使用new,而使用std::make_uniquestd::make_shared。例如,更好的解决方案是这样的:

#include <iostream>
#include <memory>
#include <stdexcept>

std::unique_ptr<double> foo()
{
    try {
        return std::make_unique<double>();
    }
    catch(const std::bad_alloc &)   {
        std::cout << "Error: out of memory." << std::endl;
        exit(1);
    }
}

【讨论】:

  • "exit(1);" 或(恕我直言)exit(EXIT_FAILURE);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 2011-06-25
  • 2015-10-19
  • 2013-08-03
  • 2012-09-10
相关资源
最近更新 更多