如何使用不同类型的数组正确使用memcpy

时间:2014-03-12 01:56:32

标签: c++ memcpy

我有一个名为Stack的模板类,它有一个私有方法resize

每当我使用此类的intdouble模板版本时,它都会按预期工作。但是,每当我使用模板的floatstring版本时,它都会崩溃。我相信我的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的堆分配成员变量数组。

2 个答案:

答案 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;
}