【问题标题】:How to make sure that recently created area points to NULL?如何确保最近创建的区域指向 NULL?
【发布时间】:2012-04-30 22:18:51
【问题描述】:

如何确保对于堆区域上每个分配的新空间,最近创建的指针向量元素指向 NULL?

 Ex:
   vector < Sometype* >

   vector ----------------------
          |  |  |  | ...       |
          ----------------------

   new element is pushed back but no available area so double space

   index                         x  x+1            y
   vector -------------------------------------------
          |  |  |  | ...       |   |   | ...        |
          -------------------------------------------

                               ^^^^^^^^^^^^^^^^^^^^^
                                 recently created

         x, x+1, ... y all points to the NULL 

我希望最近创建的部分上的每个空间都指向 NULL ?

【问题讨论】:

  • 您不能(合法地)访问您正在谈论的部分,那么其中的内容有什么关系呢?
  • 请问这个问题可以用英语吗?

标签: c++


【解决方案1】:

这个新空间是向量容量的一部分,而不是大小的一部分。您不需要关心它包含什么值,因为无论如何您都不允许访问它。除了你推回的一个值之外,额外的空间不是“向量的元素”,它只是未使用的空间。

就标准而言,如果需要,实现可以使用它来存储有意义的东西。例如,一个实现可以合法地将一些引人注目的值存储在未使用的内存中,这与您希望未使用的内存包含空指针的愿望相冲突。

你可以这样写代码:

v.push_back(some_value);
if (v.capacity() > v.size()) {
    size_t oldsize = v.size();
    v.resize(v.capacity(), NULL);
    v.resize(oldsize);
}

无法保证一旦您再次调整大小,这实际上会将内存设置为 0,但它可能会。所以它可能足以用于调试。如果您的目的不是调试,请说出它是什么,因为如果不调试,那么您的目的是非法的,或者我们中的一个人误解了某些东西。

【讨论】:

    【解决方案2】:

    如果我正确理解了您的问题,一个简单的解决方案是自己调用 resize() 并传递 NULL as second argument 以用作新创建项目的默认值:

    if (v.size() == v.capacity()) //vector is full
    {
        //compute the new size
        size_t newSize = 2 * v.size();
    
        //second argument is the default value for newly added items
        v.resize(newSize, NULL); 
    }
    

    【讨论】:

    • 据我所知,答案不正确/具有误导性。即使您不提供第二个参数,std::vector 也会对新元素进行零初始化。见this answer
    【解决方案3】:

    除非它已被构造,否则为什么需要它为 NULL?例如,如果您创建一个包含 10 个对象的向量,然后将额外的第 11 个项目推送到该向量上,则该向量可能保留足够的空间容纳另外 10 个项目,但除非您推送,否则您不能使用这些项目将项目添加到增加其大小的向量上,或者您调用resize

    sizecapacity不一样

    【讨论】:

      【解决方案4】:

      你为什么需要那个? vector 无论如何都不允许您访问这些元素。其容量的扩展是向量的实现细节,分配空间的元素值是不相关的。一旦你在那里push_backresize 具有给定值的向量,这些元素将被覆盖。

      向量的capacitysize之间有一个重要的区别。

      【讨论】:

        【解决方案5】:

        当你将新元素压入vector并且没有空间时,虽然std::vector为新元素分配了额外的内存(类似于reserve()调用),但它不会创建它们(不会调用构造函数)。请参阅placement "new" 以了解其工作原理。没有真正的方法来为新元素强制执行某些值,因为没有新元素 - 只有为未来元素分配的原始内存块。通过使用 std::vector::at 而不是 operator[],您可以确保您正在访问有效范围内的元素。

        如果您通过调用std::vector::resize 自己调整矢量大小,则只需在第二个参数中为新元素提供默认值。但是,有一个问题。当您自己调整 std::vector 的大小并且不为 std::vector::resize 的第二个参数提供值时,如果存储在 std::vector 中的值具有构造函数并对它们进行零初始化,则 std::vector 将对新元素进行值初始化否则。这意味着,如果您执行std::vector&lt;int*&gt; v; v.resize(200);,则 v 的所有新元素都将初始化为零。详情见this答案。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多