我搜索过类似的问题,但找不到符合我需求的问题。
我是一名计算机科学专业的学生,目前正在学习算法和数据结构。在我的考试中,我必须用C++实现一组模板化的数据结构。我不被允许使用STL,因为这是一道关于如何实现类似STL的库的考试题。
我的实现是可行的,但是我想向您征求关于动态内存分配的建议。
其中一些数据结构使用动态数组(实际上是一个原始指针(来存储元素,当元素满了时,它会自动增长,并在一定的负载因子阈值下收缩(大小分别翻倍和减半(。为了简单起见(也因为我不应该使用它们(,我没有使用任何"现代的东西",比如智能指针或移动构造函数/运算符,基本上我依赖C++98的功能。我使用了new[]和 delete[]我的问题是:在C++中,处理基于数组的数据结构的动态内存分配的正确方法是什么? 下面是我所做的一个例子(数组之前已由new[]分配(:template <typename T>
void ArrayList<T>::pushBack(T item)
{
if (size < capacity) { // if there's room in the array
array[size] = item; // simply add the new item
} else { // otherwise allocate a bigger array
capacity *= 2;
T *temp = new T[capacity];
// copy elements from the old array to the new one
for (int i = 0; i < size; ++i)
temp[i] = array[i];
delete [] array;
temp[size] = item;
array = temp;
}
++size;
}
不,您仍然不需要new
和delete
。在C++中仍然使用new
的唯一原因是执行聚合初始化,而std::make_unique
不支持聚合初始化,而且您根本不需要delete
。
然后您的代码示例变为:
template <typename T>
void ArrayList<T>::pushBack(T item)
{
if (size < capacity) { // if there's room in the array
array[size] = item; // simply add the new item
} else { // otherwise allocate a bigger array
capacity *= 2;
auto temp = std::make_unique<T[]>(capacity);
// copy elements from the old array to the new one
for (int i = 0; i < size; ++i)
temp[i] = array[i];
temp[size] = item;
array = std::move(temp);
}
++size;
}
这也可以通过交换两个部分来降低:
template <typename T>
void ArrayList<T>::pushBack(T item)
{
if (size >= capacity) { // if there's no room in the array, reallocate
capacity *= 2;
auto temp = std::make_unique<T[]>(capacity);
// copy elements from the old array to the new one
for (int i = 0; i < size; ++i)
temp[i] = array[i];
temp[size] = item;
array = std::move(temp);
}
array[size] = item; // simply add the new item
++size;
}
进一步可能的改进:重新定位时移动元素而不是复制它们,使用标准算法而不是手动for
循环。
我相信,对于这个项目,使用new
和delete
确实是合适的;我的数据结构老师使用了完全相同风格的内存分配。看起来,人们不赞成使用分配的内存的一般原因是很难正确管理。记住delete
所有不再使用的内存是非常重要的——不要想手头有任何孤立的RAM!