因此,我正在编写一个动态数组类,并且遇到了(我相信)设置一个临时数组来保存值的问题,然后更改了当前数组的大小,这使我发现了glibc检测到的free():无效的下一个尺寸(快速)错误。我意识到这要么意味着我正在某个数组的边界以外的地方写东西,要么是我试图释放未分配给我的内存,但是我似乎找不到问题所在。非常感谢您的帮助,我已经查看了大约2个小时的代码,除了完全删除delete语句外,似乎没有找到解决此问题的方法,这并不是解决方案,因为这只会导致内存不足泄漏。而且我是C ++的新手,因此对任何愚蠢的错误/语法表示歉意
ArrayList.cpp
#include "ArrayList.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int& ArrayList::operator[](unsigned int i){
return foo[i];
}
int ArrayList::size(){
return numElements;
}
void ArrayList::downArray(){
int* bar = foo; //temp array to hold values while I decrease the size
capacity /= 2;
delete foo;
foo = new int[capacity]; //don't I lose the original pointer here? So why does it throw an error when I try to delete foo, as if I haven't allocated that memory?
for(int i = 0; i < capacity;i++){
foo[i] = bar[i];
}
}
void ArrayList::upArray(){
int* bar = foo; //temp array to hold values while I increase the size
delete foo;
foo = new int[capacity*2]; //same thing here
foo = bar;
for(int i = capacity; i < capacity*2;i++){
foo[i] = 0;
}
capacity *=2;
}
void ArrayList::push_back(int m){
if(numElements == capacity) //full, double foo
upArray();
foo[numElements] = m;
numElements++;
}
void ArrayList::erase(int m){
bool notFound = true;
int i = 0;
while(notFound)
if(foo[i] == m){
notFound = false; //Ha! Found you!
for(int j = i; j+1 < capacity; j++){
foo[j] = foo[j+1]; //moves everything to right of m one spot left
}
}
else
i++; //keep looking
}
string ArrayList::toString(){
stringstream sobj;
string x;
sobj << "[";
for(int i = 0; i < numElements; i++){
if(i == numElements-1) //last iteration, avoids output displaying [1,2,3,4,]
sobj << foo[i];
else
sobj << foo[i] << ",";
}
sobj << "]";
sobj >> x;
return x;
}
ArrayList::ArrayList(){
capacity = 1;
numElements = 0;
foo = new int[1];
foo[0] = 0;
}
ArrayList::~ArrayList(){
//delete foo; //is this not the proper place to call it?
cout << "Destructor called" << endl;
}
ArrayList.h
#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
#include <string>
class ArrayList
{
public:
ArrayList();
~ArrayList();
int& operator[](unsigned int i); // int& ArrayList::operator[](unsigned int i){....}
void push_back(int m);
void erase(int m);
std::string toString();
int size();
private:
void downArray();
void upArray();
private:
int capacity, numElements;
int* foo;
};
#endif
主功能
int main(int argc,char *argv[])
{
ArrayList arr;
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
cout << "Should contain numbers 1..50, is ";
cout << arr.toString() << endl;
}
此代码有多个问题:
int* bar = foo; //temp array to hold values while I increase the size
delete foo;
foo = new int[capacity*2]; //same thing here
foo = bar;
for(int i = capacity; i < capacity*2;i++){
foo[i] = 0;
}
capacity *=2;
以下是此代码的一些问题:
delete foo;
一旦调用delete
,内存就被释放。因此bar
,由于指向已释放的内存,您不能再使用它。
foo = bar;
您刚刚分配了内存并将指针保存在中foo
,此行将丢弃该内存地址,并foo
重新设置为原来的地址。
一种方法upArray
是分配新的内存,复制数据,然后释放旧的内存。
int* bar = new int[capacity*2]; // new array to hold values
// Copy the data
for(int i = 0; i < capacity;i++){
bar[i] = foo[i];
}
// Zero out the rest
for(int i = capacity; i < capacity*2;i++){
bar[i] = 0;
}
delete foo; // delete the old memory
foo = bar; // point to the new memory.
capacity *=2;
还要注意,由于在成员变量中有自己分配的指针,因此必须创建一个复制构造函数和赋值运算符(请参阅“三则规则”)。否则,任何复制ArrayList
对象的代码都会复制该指针,从而导致同一内存的多次删除。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句