【问题标题】:Dynamic bool array in C++C++中的动态布尔数组
【发布时间】:2011-08-05 19:53:43
【问题描述】:
// All right? This is really good working code? 
//Need init array with value "false"

bool **Madj;
int NodeCount=4;

bool **Madj = new bool*[NodeCount];
for (int i=0; i<NodeCount; i++){
    Madj[i] = new bool [NodeCount];
    for (int j=0; j<NodeCount; j++){
        Madj[i][j] = false;
    }
}

【问题讨论】:

  • 你测试了吗?错误是什么,您的问题是什么?
  • 是的,这将创建一个 4x4 的布尔矩阵。不,不是特别好; Madj不需要声明两次,代码容易出现内存泄漏。
  • @Emile:确实如此,但我不确定它不属于这里投票关闭。 Code Review 仍处于测试阶段,因此我们无法在此处提出问题。

标签: c++ arrays dynamic boolean


【解决方案1】:

您可以考虑使用 Boost 的内置 multi-dimensional array 作为不那么脆弱的替代方案。如前所述,您提供的代码可以工作,但有问题。

【讨论】:

    【解决方案2】:

    怎么样:

    std::vector<std::vector<bool> >   Madj(4,std:vector<bool>(4, false));
    

    不幸的是 std::vector 专门用于优化大小(而不是速度)。
    所以它可能效率低下(尤其是在大量使用的情况下)。所以你可以使用一个 int 数组(如果你发现 bool 版本会减慢你的速度)。

    std::vector<std::vector<int> >   Madj(4,std:vector<int>(4, 0));
    

    注意:int 可以在布尔上下文中使用并自动转换(0 => false,任何其他数字为 true(尽管最好使用 1)。

    【讨论】:

      【解决方案3】:

      至少在 IMO,如果你坚持这样做,你通常应该采取不同的做法,例如:

      class bool_array { 
           bool *data_;
           size_t width_;
      
           // no assignment or copying
           bool_array &operator=();
           bool_array(bool_array const &);
      public:
           bool_array(size_t x, size_t y) width_(x) {
               data_ = new bool[x*y];
               std::fill_n(data_, x*y, false);
           }
      
           bool &operator()(size_t x, size_t y) { 
               return data_[y+width_+x];
           }
      
           ~bool_array() { delete [] data_; }
      };
      

      这可以被修饰(例如,使用代理来强制执行 constness),但总体思路仍然存在:1)将您的 bools 分配在一个块中,2)将它们放入一个类中,3)重载支持对数据进行合理干净的索引的运算符。

      您还应该考虑使用std::vector&lt;bool&gt;。与std::vector 的其他实例不同,它不是一个容器(正如标准定义的那样),这可能会令人困惑——但您创建的也不是一个容器,因此这对您来说显然无关紧要。

      【讨论】:

      • 如果发生内存泄漏,使用 for 循环填充它有什么潜在危险?你能指出我在网络上的一些文章吗?
      • @Hossein:我不太确定你在问什么。将其封装到对象中的部分想法是确保内存不会泄漏。
      【解决方案4】:
      bool **Madj = new bool*[NodeCount];
      for (int i=0; i<NodeCount; i++){
          Madj[i] = new bool [NodeCount];
          for (int j=0; j<NodeCount; j++){
              Madj[i][j] = false;
          }
      }
      

      如果对new 的第一次调用成功但循环中的任何一个调用失败,则由于Madj 存在内存泄漏,并且直到当前i 的子数组未被删除。使用vector&lt;vector&lt;bool&gt; &gt; 或大小为NodeCount * NodeCountvector&lt;bool&gt;。使用后一个选项,您可以使用 [i*NodeCount+j] 访问元素 (i,j)。

      【讨论】:

        【解决方案5】:

        我觉得这看起来不错!

        根据用途,您可以使用 std::vector 代替原始数组。

        但确实第一个 Madj 声明应该是“extern”以避免链接或隐藏错误。

        【讨论】:

        • 这是真的,但它们只是潜力。如果您的办公桌上有一个花瓶,它可能会掉在地板上而坠毁。
        • (指的是我指出的内存泄漏;我后来删除了评论):你在为当今世界可能会花费大笔钱或生命的那种草率编程辩护。
        • @larsmans 马虎的部分是当您忘记重新分配内存时。依靠自动保障只会将问题转移到其他地方。内存泄漏和崩溃只是周围所有错误的一小部分,并且您没有针对错误实现的逻辑的自动保护措施。我完全支持OP的代码。我知道它会产生内存释放错误的“风险”,但每个代码行都是错误的潜在来源。
        • OP 的代码不是潜在的错误来源,它包含错误。
        • @larsmans 除了可能被编译器-链接器工具链捕获的 Madj 的重复声明之外,它是否包含其他错误?
        【解决方案6】:

        如果您只有bools,请考虑使用bitsets。您可以将其与多维数组的其他容器结合使用,例如 vector&lt;bitset&gt;

        【讨论】:

          猜你喜欢
          • 2013-09-28
          • 2014-06-11
          • 2019-11-20
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 1970-01-01
          • 2011-10-02
          • 1970-01-01
          相关资源
          最近更新 更多