So I'm writing a dynamic array class and I'm running into issues with (I believe) setting up a temporary array to hold the values, then changing the size of the current array, it throws me the glibc detected free(): invalid next size(fast) error. I realize that this either means I'm writing outside of an array's bounds somewhere, or I'm trying to free memory that I don't have allocated to me, but I can't seem to find where the issue is.. Any help would be greatly appreciated, I've been looking over my code for about 2 hours and can't seem to find a way to fix the issue besides removing the delete statements altogether which isn't much of a solution since that just causes memory leaks. And I'm new to C++ so I apologize for any dumb mistakes/syntax
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
main function
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;
}
This code has multiple problems:
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;
Here are some issues with this code:
delete foo;
Once you call delete
, the memory is freed. So you can no longer use bar
as it points to freed memory.
foo = bar;
You just allocated memory and saved the pointer in foo
, this line throws away that memory address and sets foo
back to what it was.
One way to do the upArray
is to allocate the new memory, copy the data across, then free the old memory.
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;
Also note that as you have your own allocated pointers in your member variables, you must create a copy constructor and assignment operator (see Rule Of Three). Otherwise any code that makes a copy of an ArrayList
object will copy the pointer, leading to multiple deletes of the same memory.
`ArrayList arr;` will call the constructor
ArrayList::ArrayList(){
capacity = 1;
numElements = 0;
foo = new int[1];
foo[0] = 0;
}
Which is creating foo of size 1. then
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
push_back method can only insert one elemnt(because size is 1). Solution : change the for loop for (int i=1;i<=1;i++)
so toString should print only one element.I did't compiled your source code. It's my basic understanding.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.