在 C++ 中释放分配器
deallocate of allocator in C++
我定义了一个 class 模板 Vec,它包含一个 T 序列,例如向量:
template <typename T> class Vec {
public:
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
T *begin() const { return elements; }
T *end() const { return first_free; }
void resize(const size_t); // something wrong in this function
...
private:
allocator<T> alloc; //allocates the elements
T *elements; // pointer to the first element in the array
T *first_free; // pointer to the first free element in the array
T *cap; // pointer to one past the end of the array
...
};
当我的代码调用这个函数时,程序会崩溃,
template <typename T> void Vec<T>::resize(const size_t newcap)
{
// this part goes well
if(newcap > capacity()) {
auto newdata = alloc.allocate(newcap);
auto dest = newdata;
auto orig = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*orig++));
elements = newdata;
first_free = dest;
cap = elements + newcap;
}
// crash happens in the following two parts
else if(size() <= newcap && newcap < capacity()) { // deallocate the redundant memory where no element exists
alloc.deallocate(elements + newcap, capacity() - newcap); // this line causes crash
cap = elements + newcap;
}
else if(size() < newcap) { // destroy the elements and deallocate the memory
for(auto p = first_free; p != elements + newcap; /*empty*/)
alloc.destroy(--p);
alloc.deallocate(elements + newcap, capacity() - newcap); // this line causes crash
first_free = cap = elements + newcap;
}
}
调用代码:
Vec<string> v{"aaa", "bbb", "ccc"}; // size() == 3, capacity == 3
v.resize(2); // to resize v to size() == 2, capacity == 2
我想我已经进行了正确的解除分配调用和正确的指针算法。谢谢。
alloc.deallocate(elements + newcap, capacity() - newcap);
你不能那样做。 Allocator are all or nothing:你要么取消分配整个分配的块,要么不理会它。
要缩小分配的内存,执行与新大小大于当前容量时相同的分配和复制操作,但分配新的较小大小。
顺便说一句,标记为//this part goes well
的部分有一个主要问题:它从不释放旧内存块。
我定义了一个 class 模板 Vec,它包含一个 T 序列,例如向量:
template <typename T> class Vec {
public:
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
T *begin() const { return elements; }
T *end() const { return first_free; }
void resize(const size_t); // something wrong in this function
...
private:
allocator<T> alloc; //allocates the elements
T *elements; // pointer to the first element in the array
T *first_free; // pointer to the first free element in the array
T *cap; // pointer to one past the end of the array
...
};
当我的代码调用这个函数时,程序会崩溃,
template <typename T> void Vec<T>::resize(const size_t newcap)
{
// this part goes well
if(newcap > capacity()) {
auto newdata = alloc.allocate(newcap);
auto dest = newdata;
auto orig = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*orig++));
elements = newdata;
first_free = dest;
cap = elements + newcap;
}
// crash happens in the following two parts
else if(size() <= newcap && newcap < capacity()) { // deallocate the redundant memory where no element exists
alloc.deallocate(elements + newcap, capacity() - newcap); // this line causes crash
cap = elements + newcap;
}
else if(size() < newcap) { // destroy the elements and deallocate the memory
for(auto p = first_free; p != elements + newcap; /*empty*/)
alloc.destroy(--p);
alloc.deallocate(elements + newcap, capacity() - newcap); // this line causes crash
first_free = cap = elements + newcap;
}
}
调用代码:
Vec<string> v{"aaa", "bbb", "ccc"}; // size() == 3, capacity == 3
v.resize(2); // to resize v to size() == 2, capacity == 2
我想我已经进行了正确的解除分配调用和正确的指针算法。谢谢。
alloc.deallocate(elements + newcap, capacity() - newcap);
你不能那样做。 Allocator are all or nothing:你要么取消分配整个分配的块,要么不理会它。
要缩小分配的内存,执行与新大小大于当前容量时相同的分配和复制操作,但分配新的较小大小。
顺便说一句,标记为//this part goes well
的部分有一个主要问题:它从不释放旧内存块。