c++ - 将元素插入动态数组的后面时,有没有办法防止写访问冲突?
问题描述
我想使用该insertBack()
函数将元素添加到数组的后面;但是,当我尝试这样做时出现错误:
抛出未处理的异常:写访问冲突。this->arr 是 0x1110116。
我不确定我做错了什么;我教授的职位和前提条件让我感到困惑。我也不知道如何使用 allocate 以及我将容量翻倍的方法是否正确。
容器类:
#include <iostream>
template<typename T>
class container
{
template <typename T2>
friend std::ostream& operator<<(std::ostream& out, const container<T2> &cobj);
// Postcondition: contents of the container object cobj is displayed
public:
container();
// Postcondition: an empty container object is created with data members
// arr set to NULL, n set to -1 and Capacity set to 0
~container();
// Destructor; required as one of the Big-3 (or Big(5) because of the
// presence of a pointer data member. Default version results in
// memory leak!
// Postcondition: dynamic memory pointed to by arr has been release back to
// the “heap” and arr set to NULL or nullptr
// In order to see the action, message "destructor called and
// dynamic memory released!" is displayed
bool isEmpty() const;
// Postcondition: returns true is nothing is stored; returns false otherwise
bool isFull() const;
// Postcondition: returns true if arr array is filled to capacity;
// returns false otherwise
int size() const;
// Postcondition: returns the size or the number of elements (values)
// currently stored in the container
int capacity() const;
// Postcondition: returns the current storage capacity of the container
bool insertBack(const T& val);
// Postcondition: if container is not full, newVal is inserted at the
// end of the array;
// otherwise, double the current capacity followed by the insertion
private:
void allocate(T* &temp);
// Postcondition: if Capacity = 0, allocate a single location;
// otherwise the current capacity is doubled
T *arr;
int Capacity; // Note: Capital 'C' as capacity is used as a function name
int n; // size or actual # of values currently stored in the container;
// n <= SIZE
};
功能定义/代码:
template<typename T2>
std::ostream& operator<<(std::ostream& out, const container<T2> &cobj)
{
std::cout << "Currently it contains " << cobj.size() << " value(s)" << std::endl
<< "Container storage capacity = " << cobj.capacity() << std::endl
<< "The contents of the container:" << std::endl;
if (cobj.isEmpty())
{
std::cout << "*** Container is currently empty!" << std::endl;
}
else
{
for (int i=0; i<cobj.size(); ++i)
{
std::cout << cobj.arr[i];
}
}
return out;
}
template<typename T>
container<T>::container()
{
arr = nullptr;
Capacity = 0;
n = 0;
}
template<typename T>
container<T>::~container()
{
delete arr;
arr = nullptr;
std::cout << "Destructor called! (this line is normally not displayed)"
<< std::endl;
}
template<typename T>
bool container<T>::isEmpty() const
{
return n==0;
}
template<typename T>
bool container<T>::isFull() const
{
return n==Capacity;
}
template<typename T>
int container<T>::capacity() const
{
return Capacity;
}
template<typename T>
int container<T>::size() const
{
return n;
}
template<typename T>
bool container<T>::insertBack(const T& val)
{
if (size()>=Capacity)
{
Capacity = Capacity*2;
n++;
arr[n] = val;
return true;
}
else
{
return false;
}
}
template<typename T>
void container<T>::allocate(T* &temp)
{
if (Capacity==0)
{
temp = new T;
}
else
{
return Capacity*2;
}
}
int main()
{
container<int> a1;
std::cout << a1 << std::endl;
std::cout << "Currently, the container object contains 0 element(s) or 0 value(s)"
<< std::endl;
std::cout << "\nWe now insert 3 values at the back of the array, one at a time:"
<< std::endl;
const int num = 3;
for (int i=0, c=0; i<=num; ++i, c+=10)
{
a1.insertBack(c);
}
std::cout << a1;
}
解决方案
当你使用insertback()
andsize() >= Capacity
时,你的数组并没有真正扩展。您只需将名为的变量加倍Capacity
,但数组本身实际上并没有加倍。
您可以尝试使用此代码将数组加倍,如下所示:
T* old_array = arr; arr = new T[Capacity<<=1]; //double array
for(int i=0;i<n;++i) arr[i]=old_array[i] //copy you can use memcpy instead for loop
delete [] old_array; //free space
在您的代码中发现了一些其他错误:
析构函数
你应该
delete []arr
改用delete arr
.delete
释放分配了指向 new的单个对象指针的内存。delete []
释放新分配的对象数组指针指向的内存。并且记得在使用 delete 之前检查 arr 是否为 nullptr。
insertback
arr[n]=val;
之前使用n++;
。void container<T>::allocate(T* &temp)
的返回类型
allocate()
是void。因此你不能return Capacity*2;
。
小费:
我建议为Container
. 所以在没有指定容量的时候,请求默认容量空间,而不是把容量设置为零。
推荐阅读
- python - ModuleNotFoundError:没有名为“ntlk”的模块
- javascript - Socket.io 客户端未收到事件
- c# - 如何缩短大型 if-else 场景?
- javascript - 用户界面网格;遍历对象
- spring-boot - 了解 spring-security 上的 requestMatchers()
- cmake - 'LoadFile' 不是 YAML 的成员
- botframework - 如何使用 Cosmos DB 模拟器在 Bot Framework 中关闭 SSL 验证
- android - 没有浏览器警告的有效 https 连接到本地网络中的服务器
- c# - 如何正确地将 DateTime 转换为特定的 TimeZone?
- css - 3D 翻转动画... 背面可见性问题