【问题标题】:C++ double* array, test allocationC++ double* 数组,测试分配
【发布时间】:2012-07-09 19:10:23
【问题描述】:

我有一些疑问:我想测试在函数调用之前是否已经分配了一些数组,低和高。函数从这个测试开始:

bool myMgr::compute(myInput *solvInput, double* low, double* high)
{
   if(high==NULL||low==NULL)
        return false;

   //...
}

我在测试什么,我测试对了吗?

感谢和问候

【问题讨论】:

  • if( !high || !low ) 看起来更好,也能胜任。
  • @SingerOfTheFall 如果highlow 是指针。在它们上使用! 运算符会产生误导和混淆。他最初的if 是我的首选形式,虽然我对喜欢if ( high == 0 || low == 0 ) 的人有一些理解。 (我不同意,但这是一个值得商榷的立场。)当然,如果你使用的是 C++11,那就是if ( high == std::nullptr || low == std::nullptr )
  • 学究式地,您不是在调用之前而是在调用之后测试分配。测试在函数体内。此外,测试分配失败不是很实用(除了在一些非常特殊的情况下):通常,您不能对它们做任何事情,只能中止一切。如果这就是你要做的事情,为什么不直接崩溃呢?
  • @James Kanze 为什么我更喜欢if ( high == 0 || low == 0 ) 而不是我的解决方案,有什么不同?
  • @fork0 我的老板不让我崩溃

标签: c++ arrays pointers null


【解决方案1】:

您正在测试这两个指针是否不为 NULL,如果堆分配器无法分配足够的内存,它们将返回该值,但除此之外您不能做出其他假设:

  • 它们可能是!= NULL,但由用户初始化:double* ptr = (double*)5;
  • 它们可能是也可能不是“数组”:您没有关于分配的元素数量的信息。

【讨论】:

  • 如果堆分配器无法分配内存,则会引发std::bad_alloc 异常。
  • 确实,但不一定:运算符new 有一个nothrow 版本,它返回NULL 而不是引发异常。但无论如何,如果引发异常,程序会在其compute 函数调用之前意识到它(如果它被捕获)或程序崩溃。我的意思是强调对NULL 值的检查并不严格等于内存已分配
  • 有几种方法可以避免异常,但在通常情况下......无论如何,我只是对那一个陈述提出质疑,而不是整个答案。正如你所说,没有办法真正知道指针是否有效(尽管使用 Boehm 收集器有很大帮助)。
【解决方案2】:

是的,你所做的是正确的。但是您必须确保在声明期间(在调用方法中)已将指针初始化为 NULL - 否则,它们可能包含会通过此测试的垃圾值。

【讨论】:

    【解决方案3】:

    如果您有最新版本的 c++(来自 c++11),您应该使用 nullptr 而不是 NULL

    if(high==nullptr || low==nullptr)
    

    并且您必须确保将指针设置为 nullptr 而不是 NULL

    如果nullptr 不可用,那么您正在做的事情很好,或者,您可以按照 SingerOfTheFall 在他的评论中写的那样做。

    此外,您可以使用std::vector,而不是使用数组并且必须依赖指针,这将允许您获得有关数组当前状态的更多信息,例如它的当前大小。

    【讨论】:

    • 设置指向nullptrNULL0的指针都具有完全相同的效果。
    • @JamesKanze 是的,但是你不能错误地将nullptr 分配给int,而你可以使用NULLO
    • 如果您的所有目标编译器都支持它,那么使用nullptr 肯定更好。但是,如果您将NULL 分配给int,好的编译器会发出警告。 (出于显而易见的原因,如果将0 分配给int,编译器不会发出警告。这就是我更喜欢NULL 而不是0 的原因之一。)
    【解决方案4】:

    你无法检查指针是否指向有效的东西。

    您可以将数组作为引用传递,这样可以确保函数至少接收初始化参数,但最好使用向量:

    compute(std::vector<myInput> &solvInput, std::vector<double> &low, std::vector<double> &high)
    

    如果他们是 1:1 的话,甚至更好地把低和高放在一个班级里

    compute(std::vector<myInput> &solvInput, std::vector<minmax> &lowhigh)
    

    【讨论】:

      【解决方案5】:

      你提到了分配。这是误导;通常的分配器从不返回一个空指针。如果内存不足,它们会引发std::bad_alloc 异常。

      如果您要提供某种可选行为,则使用这样的指针很有用;客户端代码可以传递一个空指针来指示它不需要您提供的功能。 (当然,客户端代码可以自己进行测试,并且只有在两个指针不为空时才调用您的函数。哪种解决方案更可取很大程度上取决于上下文。)

      【讨论】:

        猜你喜欢
        • 2012-10-29
        • 2012-04-24
        • 2013-03-13
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 2015-07-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多