数组 class 中的 malloc 和 memcpy 问题

Problem with malloc and memcpy in array class

我已经开始为 List class 编写一些代码,但我迷路了。我的 Arduino 项目需要它——我不能使用 STL。

这是代码。

#include <iostream>
    
template <typename T>
class List
{
public:
    List<typename T>()
    {
        m_Count = 0;
        m_Data = nullptr;
    }
    
    ~List()
    {
        free(m_Data);
    }
    
    void Push(const T& element)
    {
        m_Count++;
        T* alloc = (T*)malloc(size_t(sizeof(T) * m_Count));
        memcpy(alloc, m_Data, m_Count * sizeof(T));
        *(m_Data + sizeof(T) * (m_Count - 1)) = element;
    }
    
    T* operator [](unsigned int x) const
    {
        return (m_Data + x * sizeof(T));
    }
    
private:
    T* m_Data;
    uint64_t m_Count;
    
};
    
struct Vertex
{
    int x;
    int y;
};
    
int main()
{
    List<Vertex> list;
    list.Push({ 0, 1 });
    list.Push({ 2, 3 });
    list.Push({ 4, 5 });
    
    std::cout << list[0]->x << list[1]->x << list[2]->x;
}

问题出在Push方法的某处:当我调用memcpy时,程序触发了编译断点。

根本问题在*(m_Data + sizeof(T) * (m_Count - 1)) = element;行。在这里,您试图将给定的 element 复制到 old(即预先存在的)m_Data 数组中;这将是 nullptr 第一次调用 Push 函数(并且每隔一次调用一个元素太小).

因此,您需要先释放旧数据(free(m_Data)),然后将新分配的内存分配给该指针(m_Data = alloc),然后才复制element 到该数组的最后一个元素。

但是,正如其他人所说,为什么要在 C++ 中使用 mallocfree?下面的代码将这些调用替换为 new[]delete[](尽管如果可能的话,使用 std::vector 可能会是 easier/better/safer)。

#include <iostream>

template <typename T>
class List {
public:
    List<T>() { // Don't need "typename" here!
        m_Count = 0;
        m_Data = nullptr;
    }
    ~List() {
        delete[] m_Data;
    }
    void Push(const T& element) {
        m_Count++;
        T* alloc = new T[m_Count];
        for (uint64_t i = 0; i < m_Count - 1; ++i) alloc[i] = m_Data[i]; // Copy old data (if any)
        delete[] m_Data; // Release old data
        m_Data = alloc; // Assign newly-allocated memory to m_Data
        m_Data[m_Count - 1] = element; // Why use pointer arithmetic when you have the [] operator?
    }
    T* operator [](unsigned int x) const {
        return &m_Data[x];
    }

private:
    T* m_Data;
    uint64_t m_Count;

};

struct Vertex {
    int x;
    int y;
};

int main()
{
    List<Vertex> list;
    list.Push({ 0, 1 });
    list.Push({ 2, 3 });
    list.Push({ 4, 5 });
    std::cout << list[0]->x << list[1]->x << list[2]->x << std::endl;
    std::cout << list[0]->y << list[1]->y << list[2]->y << std::endl;
    return 0;
}

我对你的代码做了一些其他的 'minor improvements' (你的 operator [] 看起来很可疑,因为在进行指针运算时,指向对象的大小在本质上被考虑在内) ;还有其他 可以 制作,但是恕我直言,这与您发布的代码相差太远。


实际上,它在您的代码中 总是nullptr,因为您永远不会向它分配任何其他内容。