我正在尝试实现常规连续动态数组的替代方法,其中我使用指针向量,每个都指向一个恒定大小的数组,将其称为XVector。
它适用于某个输入限制 - 比如150个元素 - 但除此之外它会开始抛出异常。
我尝试使用“new and delete”而不是“malloc and free”,它确实增加了限制 - 比如大约1200个元素 - 但仍然存在同样的问题。
我正在使用C ++。
这是我的主要计划:
XVector<int> xv;
for(int i=0;i<1210;i++){
int temp = rand()%100;
xv.pushBack(temp);
}
for(int i=0;i<xv.size();i++){
cout<<xv.getValue(i)<<" ";
}
cout<<"\n\n"<<xv.capacity();
return 0;
这是XVector(D头文件的类:
private:
const int b = 10;
vector<T*> arr;
int currentIndex;
int maxSize;
protected:
void expand(){
T* temp = new T[b];
arr.push_back(temp);
maxSize+=(b);
}
void shrink(){
delete[] arr[arr.size()-1];
arr[arr.size()-1] = NULL;
arr.pop_back();
maxSize-=(b);
}
int ceil(float num) {
int inum = (int)num;
if (num == (float)inum) {
return inum;
}
return inum + 1;
}
pair<int,int> position(int index){
pair<int,int> pos;
float result = ((float)index/b);
pos.first = result; //Row #
pos.second = ceil((result - pos.first)*b); //Exact cell in the row
return pos;
}
public:
XVector(){
currentIndex=0;
maxSize=b;
arr.reserve(120);
arr.push_back(new T[b]);
}
void pushBack(T value){
if(currentIndex>=maxSize-1){expand();}
pair<int,int> indeces = position(currentIndex);
arr[indeces.first][indeces.second]=value;
currentIndex++;
}
void popBack(){
currentIndex--;
if(maxSize>=currentIndex+(2*b)){shrink();}
}
T getValue(int index){
pair<int,int> indeces = position(index);
return arr[indeces.first][indeces.second];
}
void setValue(int index,T value){
pair<int,int> indeces = position(index);
arr[indeces.first][indeces.second] = value;
}
int capacity(){
return maxSize;
}
int size(){
return currentIndex;
}
bool empty(){
return currentIndex==0?true:false;
}
PS:我试图使用Valgrind,但未能确定确切的问题。
答案 0 :(得分:4)
你的程序泄漏了内存,因为你永远不会释放析构函数中的指针。您必须实现析构函数来解决内存泄漏(除了移动构造函数,复制构造函数,赋值复制和赋值移动)。
除了valgrind之外,您还可以使用ASAN,它具有更好的输出并且运行速度更快。
答案 1 :(得分:0)
代码导致代码崩溃的主要问题不是内存泄漏。完全内存泄漏不会导致短期崩溃。在内存泄漏情况下你的应用程序工作,直到你的RAM上有足够的空间,然后如果你的RAM已满,发生崩溃。你在 position()方法中查找第二个维度索引时出错。
例如,当您调用position(index:29)因为执行float和float精度时,(结果 - pos.first)* b 的结果是 9.00000095 。这意味着它的结果与实际结果有一点差异(9)。然后你打电话给 ceil(9.00000095),结果返回10。这意味着您可以访问第二个维度的索引10,而您可以使用0到9之间的索引,并且索引超出范围访问会导致您在一段时间后崩溃并且您的程序可能具有未定义的行为。
位置法的正确样本是:
pair<int, int> position(int index){
pair<int, int> pos;
float result = ((float)index / b);
pos.first = result; //Row #
pos.second = index%b; // changed line
return pos;
}
最后,您应该定义析构函数并删除由新运算符分配的所有内存。需要删除所有向量元素(数组)。