Templates 容器模板类-减小容器大小

Templates 容器模板类-减小容器大小,templates,segmentation-fault,const-iterator,Templates,Segmentation Fault,Const Iterator,我已经编写了一些代码来减少模板化容器类的容量。从容器中删除一个元素后,erase函数检查总空间的25%是否正在使用,以及将容量减少一半是否会导致其小于我设置的默认大小。如果这两个函数返回true,那么将运行缩小函数。但是,如果这发生在我在一个常数迭代循环的中间,我会得到一个Sebug。p> 再次编辑:我认为这是因为const_迭代器指针指向旧数组,需要指向由downsize()创建的新数组……现在如何进行此操作 template <class T> void sorted<T&

我已经编写了一些代码来减少模板化容器类的容量。从容器中删除一个元素后,erase函数检查总空间的25%是否正在使用,以及将容量减少一半是否会导致其小于我设置的默认大小。如果这两个函数返回true,那么将运行缩小函数。但是,如果这发生在我在一个常数迭代循环的中间,我会得到一个Sebug。p> 再次编辑:我认为这是因为const_迭代器指针指向旧数组,需要指向由downsize()创建的新数组……现在如何进行此操作

template <class T>
void sorted<T>::downsize(){

  // Run the same process as resize, except
  // in reverse (sort of). 
  int newCapacity = (m_capacity / 2);
  T *temp_array = new T[newCapacity];

  for (int i = 0; i < m_size; i++)
    temp_array[i] = m_data[i];

  // Frees memory, points m_data at the 
  // new, smaller array, sets the capacity
  // to the proper (lower) value.
  delete [] m_data;
  m_data = temp_array;
  setCap(newCapacity);
  cout << "Decreased array capacity to " << newCapacity << "." << endl;  
}


// Implementation of the const_iterator erase method.
template <class T>
typename sorted<T>::const_iterator sorted<T>::erase(const_iterator itr){  

  // This section is reused from game.cpp, a file provided in the
  // Cruno project. It handles erasing the element pointed to
  // by the constant iterator.
  T *end = &m_data[m_capacity];    // one past the end of data
  T *ptr = itr.m_current;        // element to erase

  // to erase element at ptr, shift elements from ptr+1 to 
  // the end of the array down one position
  while ( ptr+1 != end ) {
    *ptr = *(ptr+1);
    ptr++;
  }

  m_size--;

  // Once the element is removed, check to
  // see if a size reduction of the array is
  // necessary.
  // Initialized some new values here to make
  // sure downsize only runs when the correct
  // conditions are met.
  double capCheck = m_capacity;
  double sizeCheck = m_size;
  double usedCheck = (sizeCheck / capCheck);
  int boundCheck = (m_capacity / 2);
  if ((usedCheck <= ONE_FOURTH) && (boundCheck >= DEFAULT_SIZE))
    downsize();

  return itr;
}


// Chunk from main that erases.
int i = 0;
for (itr = x.begin(); itr != x.end(); itr++) {
  if (i < 7) x.erase(itr);
  i++;   
}
模板
已排序为空::缩小尺寸(){
//运行与调整大小相同的过程,除了
//相反地(有点)。
int newCapacity=(m_容量/2);
T*temp_数组=新的T[newCapacity];
对于(int i=0;icout要防止在擦除循环期间出现无效迭代器问题,可以使用:

x.erase(itr++);
与单独的增量调用和增量调用不同(显然,如果没有擦除循环中的所有内容,则需要使用else case来增量超过未擦除的项)。请注意,在这种情况下,需要使用增量后而不是增量前

不过,整个过程看起来有点效率低下。转换为数组的方式表明,它只适用于某些容器类型。如果您希望从容器的中间进行大量擦除,您可能可以通过选择不同的容器来避免内存问题;可能是列表

如果您选择vector,您可能会发现调用shrink_to_fit就是您想要的

还请注意,erase有一个返回值,该值将指向被擦除元素之后的元素(新)位置


如果将迭代器返回到新创建的容器的较小版本,请注意,与原始容器end()迭代器相比,迭代器不起作用。

我解决了segfault问题

发生的事情是,我的x.end()使用的是数组的大小(不是容量),其中大小是存储在数组中的数据元素的数量,而不是容量,容量实际上是数组的大小。因此,当它查找数组的结尾时,它将其视为实际结尾之前的许多元素


现在我们来看更有趣的问题!

不幸的是,我没有太多的选择来决定它是什么类型的容器。这是一个学校项目,所以他们给了我一长串的方法/数据成员,并说像这样去实现它。