矢量调整大小 - 检测的便携方式

Posted

技术标签:

【中文标题】矢量调整大小 - 检测的便携方式【英文标题】:vector resizing - portable way to detect 【发布时间】:2009-03-01 21:06:59 【问题描述】:

我有一个向量,我正在加载一个已知数量的元素 (N)。

处理会动态创建新元素,这些元素会附加到向量中。

我预计要创建大约 2 * N 个附加元素, 所以我将向量的大小调整为 3 * N。

如果额外的元素超过这个值,我希望程序中止,而不是动态扩展向量。

有没有办法检测到,可以在 AIX/TRU64/Linux 之间移植?

【问题讨论】:

【参考方案1】:

检测什么?矢量是否会调整大小?有没有?

实现这一点的唯一真正方法是在自定义分配器或将元素添加到向量的函数中提供检查功能。

例如

template<class T> 
void add_element(std::vector<T>& container, T const& v)

  if (container.capacity()+1 >= 3*N)
  
    // terminate/exception/whatever
  

 container.push_back(v);

【讨论】:

【参考方案2】:

为什么要使用矢量?向量的重点是在需要时动态扩展。

不要创建一个类来委托给向量,只需创建一个类来委托给一个简单的数组。让您的 push_back 检查大小并在需要时中止。

【讨论】:

【参考方案3】:

创建您自己的类来委托给向量。并在您自己的 push_back 中检查大小。

【讨论】:

【参考方案4】:

如果您在编译时知道大小,也许使用 std::tr1::array(或boost::array)会是更好的选择。它保持固定大小并像 std::vector 一样检查访问。

但是,如果您只在运行时知道它,正如其他人所说,您应该将您的向量封装在一个具有特定函数的类中,这些函数将检查您想要的条件(例如通过断言)。

在最后一种方法中,我建议,如果您可以知道创建向量时的最大大小,则在封装类构造函数(或初始化函数)。这样,向量本身将不再进行内存操作(仅当向量元素构造函数/析构函数进行此类操作时)。然后,添加一个简单的断言来检查向量容量( std::vector::capacity() )在类的所有函数的开始和结束时从未改变,这将帮助您确保它的内存不会移动。

例如(假设 DATA_MAX_SIZE 是在某处定义的默认最大尺寸):

template< typename MyType >
class MyData

public:
    MyData( unsigned long max_size = DATA_MAX_SIZE )
        : m_max_size( max_size )
         m_data.reserve( m_max_size ); 

    void add( const MyType& value )  check_capacity(); m_data.push_back( value ); check_capacity(); 



private:

    std::vector< MyType > m_data;
    const unsigned long m_max_size;

    void check_capacity()  if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); 

;

或者类似的东西......

【讨论】:

【参考方案5】:

std 类在每次插入元素时都会使用一个分配器。您可以编写一个继承自 std::alocator 的新分配器,并添加您需要的所有类型的检查/跟踪。

(我之前做过这个,但我花了一段时间来编写工作代码。)

【讨论】:

分配器不一定每次都调用,vector只会在需要扩容时才使用,不会扩容

以上是关于矢量调整大小 - 检测的便携方式的主要内容,如果未能解决你的问题,请参考以下文章

内存访问错误 - 矢量调整大小

调整对象矢量大小时出错

在调整大小时禁用矢量填充值? C++

矢量调整大小后下标超出范围

调整大小后保持对矢量元素的引用有效

Android如何以编程方式调整(缩放)xml矢量图标