gpt4 book ai didi

c++ - 自定义 vector STL 容器中的 clear() 问题

转载 作者:搜寻专家 更新时间:2023-10-31 01:59:06 26 4
gpt4 key购买 nike

根据 Accelerated C++ 中的示例,我创建了一个自定义 STL 容器,它是 std::vector 的简化版本,称为 Vec。一切工作正常,直到,在成功的鼓舞下,我尝试添加一个 Vec::clear() 来清除 vector 。

这是最新的类定义(仅与此问题相关的部分):

template <class T>
class Vec {
public:
Vec() { create(); }

size_type size() const { return avail - data; }
size_type capacity() const { return limit - data; }
void clear();

// operators that return iterators
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }

void push_back( const T& val ) {
if ( avail == limit ) grow();
unchecked_append( val );
}
private:
iterator data; // points to beginning of data
iterator avail; // points to end of initialized data
iterator limit; // points to end of data

std::allocator<T> alloc; // object to handle data allocation

void create();
// functions to support push_back()
void grow();
void unchecked_append( const T& );
};

// Creates an empty vector.
template <class T>
void Vec<T>::create() { data = avail = limit = 0; }

// All the elements of the vector are dropped: their destructors are called,
// and then they are removed from the vector container,
// leaving the container with a size of 0.
// The capacity remains the same, however.
template <class T>
void Vec<T>::clear()
{
std::cout << "capacity before clear: " << capacity() << std::endl;
std::cout << "data = " << data << " limit = " << limit << std::endl;
if (data) {
iterator it = avail;
// destroy objects in reverse order
while ( it != data ) {
alloc.destroy(--it);
}
}
data = avail = 0;
std::cout << "capacity after clear: " << capacity() << std::endl;
std::cout << "data = " << data << " limit = " << limit << std::endl;
}

// Controls how the vector should grow if it needs more space.
template <class T>
void Vec<T>::grow()
{
// Allocate twice as much storage as is currently used.
// If matrix is empty, allocate one element.
size_type new_size = std::max( 2*(limit-data), ptrdiff_t(1) );

// Allocate new space and copy existing elements
iterator new_data = alloc.allocate( new_size );
iterator new_avail = std::uninitialized_copy( data, avail, new_data );

// Deallocate old space
uncreate();

// Reset pointers to new values
data = new_data;
avail = new_avail;
limit = data + new_size;
}

// Create space for one element at the end and put given value there.
template <class T>
void Vec<T>::unchecked_append( const T& val )
{
alloc.construct( avail, val );
avail++;
}

我用

测试这个
Vec<int> v;

for ( int i = 0; i < 100; i++ ) {
v.push_back(i);
}
std::cout << "size=" << v.size() << " capacity=" << v.capacity() << std::endl;
v.clear();
std::cout << "size=" << v.size() << " capacity=" << v.capacity() << std::endl;

我得到以下输出:

size=100 capacity=128
capacity before clear: 128
data = 0x100100280 limit = 0x100100480
capacity after clear: 1074004256
data = 0 limit = 0x100100480
size=0 capacity=1074004256

出于某种原因,clear() 破坏了 limit 指针。连修改都不修改怎么会这样。代码看起来很简单,但我看不出我遗漏了什么。

谢谢!

最佳答案

通过将 data 设置为 0,您正在丢失(并因此泄漏)。当您清除时,您只是拿走了可用的(分配的)元素,缓冲区(data ) 保持不变。

您应该将 data = avail = 0; 替换为 avail = data;

关于c++ - 自定义 vector STL 容器中的 clear() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3436229/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com