卡在第11节拍的擦除功能上。我已经销毁了对象,但是我不知道如何使用分配程序库中的去分配来返回空间。
请保释我出去。PS :这不是作业,但我在家练习。
下面是加速C++的代码,然后是修改后的擦除函数。谢谢‘
template <class T> class Vec
{
public:
typedef T* iterator;
typedef const T* const_iterator;
typedef size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
Vec() { create(); }
explicit Vec(size_type n, const T& t = T()) { create(n, t); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
Vec& operator=(const Vec&);
~Vec() { uncreate(); }
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i ) const { return data[i]; }
void push_back(const T& t)
{
if (avail == limit)
{
grow();
}
unchecked_append(t);
}
iterator erase(iterator);
iterator erase( iterator, iterator );
void clear();
size_type size() const { return avail - data; }
iterator begin() { return data; }
const iterator begin() const { return data; }
iterator end() { return avail; }
const iterator end() const { return avail; }
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);
void uncreate();
void grow();
void unchecked_append(const T&);
};
我的代码
template <class T> typename Vec<T>::iterator Vec<T>::erase(iterator first, iterator second )
{
if( second < first )
{
throw std::out_of_range("Iterator out of bounds.");
}
if( first < data || second >= avail )
{
throw std::out_of_range("Iterator out of bounds.");
}
iterator last = avail -1 ;
iterator i = first ;
iterator j = second ;
while( j <= last )
{
*i++ = *j++ ;
}
// destroy each initilsed space
iterator new_avail = avail - first + second ;
std::cout << " end " << end() << std::endl;
while( avail != new_avail )
{
alloc.destroy(--avail ) ;
}
// dellocate space how to do that ?
alloc.deallocate( avail -1, ); // not sure what to do here
return first ;
}
发布于 2013-09-24 15:43:47
无法释放已分配内存的一部分。那
alloc.deallocate(效-1,);
是不好的。
编辑
您不应该尝试在擦除中对分配进行管理。你有一个选择是重新分配它,这将使擦除更加昂贵。第二种功能可以做到:
iterator shrink(iterator first, iterator last) {
size_type capacity = (limit - data) - (last - first);
iterator new_data = alloc.allocate(capacity);
iterator new_avail = new_data;
iterator source = data;
while(source < first)
// C++11
alloc.construct(new_avail++, std::move(*source++));
source = last;
iterator result = new_avail;
while(source < avail)
// C++11
alloc.construct(new_avail++, std::move(*source++));
while(data < avail)
alloc.destroy(--avail);
data = new_data;
avail = new_avail;
limit = new_data + capacity;
return result;
}
更好的选择是这种标准的方式。添加一个额外的构造函数,交换和shrink_to_fit:
Vec(const_iterator first, const_iterator last) {
create(first, last);
}
void swap(Vec& other) {
std::swap(data, other.data);
...
}
bool shrink_to_fit() {
try
{
Vec(begin(), end()).swap(*this);
return true;
}
catch(...) {}
return false;
}
现在,您可以对向量应用多个操作,并最终缩小内存消耗。
v.erase(a, b);
v.erase(c, d);
...
v.shrink_to_fit();
发布于 2013-09-24 14:30:06
我想,其中一个解决方案是创建一个大小如下的新向量:
new_size = old_size - number_of_elements_to_delete
然后将对象从开始复制到第一个擦除对象,从最后一个擦除对象复制到末尾,然后释放旧的向量。
这不是最好的解决办法,而是我想的最简单的办法。
发布于 2013-09-30 10:10:57
下面是std::allocator::deallocate
必须说的话:
void deallocate( pointer p, size_type n );
分配指针p
引用的存储,该存储必须是以前调用allocate()
获得的指针。参数n
必须等于调用最初生成p
的allocate()
的第二个参数。
也就是说,您不能释放您所分配的存储的一部分,而只能释放整个块。
解决方案是不返回通过调用erase
而空闲的存储。只需相应地更新您的成员迭代器,以便在后续调用create
时保持此存储的可维护性。这也是标准容器vector
所做的。
如果您确实希望返回多余的存储,请分配一个较小的临时块,复制驻留在容器中的元素,释放旧的存储和更新迭代器。
这里要记住的是例外安全。一旦分配了临时缓冲区,就需要确保不会泄漏它,以防在复制元素时出现异常。
https://stackoverflow.com/questions/18984165
复制相似问题