我有一个名为Stack
的模板类,它有一个私有方法resize
。
每当我使用此类的int
或double
模板版本时,它都会按预期工作。但是,每当我使用模板的float
或string
版本时,它都会崩溃。我相信我的memcpy
函数调用存在问题。我该如何正确使用它?
template <class Type>
void Stack<Type>::resize(int capacity) {
if(capacity >= MAX_SIZE)
capacity = MAX_SIZE;
Type* copy = new Type[capacity];
for (int i = 0; i < N; i++) {
copy[i] = s[i];
}
s = new Type[capacity];
memcpy(s, copy, sizeof(Type) * capacity);
size = capacity;
delete copy;
}
s
是类型Type
的堆分配成员变量数组。
答案 0 :(得分:1)
首先,使用memcpy
复制非POD类型是不正确的。只需使用for循环,或std::copy
。
其次,你做的工作超过了必要的工作(并且你有内存泄漏)。
void Stack<Type>::resize(int capacity) {
if(capacity >= MAX_SIZE)
capacity = MAX_SIZE;
Type* copy = new Type[capacity];
for (int i = 0; i < N; i++) {
copy[i] = s[i];
}
到目前为止,你没事。您已经分配了一个新数组,并分配了旧数组中的元素。我假设N
是有效元素的数量。
s = new Type[capacity];
假设s
先前指向已分配的数组,这是内存泄漏。首先,您需要删除以前的数据。
delete [] s;
然后,您不需要分配另一个数组。使用刚刚分配的那个。
s = copy;
总之,该功能现在看起来像这样:
template <class Type>
void Stack<Type>::resize(int capacity) {
if(capacity >= MAX_SIZE)
capacity = MAX_SIZE;
Type* copy = new Type[capacity];
for (int i = 0; i < N; i++) {
copy[i] = s[i];
}
delete [] s;
s = copy;
size = capacity;
}
如果仍然存在问题,代码的其他部分则会中断。
答案 1 :(得分:0)
template <class Type>
void Stack<Type>::resize(int capacity)
{
if (capacity > MAX_SIZE)
capacity = MAX_SIZE;
else if (capacity < 0)
capacity = 0;
if (capacity == size)
return;
Type* new_s = new Type[capacity];
std::copy(s, s + std::min(size, capacity), new_s);
delete[] s;
s = new_s;
size = capacity;
if (N >= size)
N = size-1;
}
或者,您可以简单地让Stack
使用std::vector
而不是原始数组,然后您就不必再担心这些细节了:
template <class Type>
class Stack
{
private:
std::vector<Type> s;
int N;
public:
void resize(int capacity);
};
template <class Type>
void Stack<Type>::resize(int capacity)
{
s.resize(capacity);
if (N >= s.size())
N = s.size()-1;
}