问题
I'm trying to create a dynamic array in my List class that will start off with a size of 2 and when you insert values with the Insert method, it will check to see if there is enough space if not it will resize the array with a size + 2... The problem is it is crashing VS is complaining about corruption of the heap. Also I think my copy constructor isn't being called because the cout's arent displaying:
list.h File:
class List
{
public:
// DEFAULT Constructor
List();
// Deconstructor to free memory allocated
~List();// Prevent memory leaks
// COPY Constructor for pointers
List(const List& value);// copy constructor
//Modification methods
void Insert(const int);
// User ACCESS methods
void display(void) const;
private:
int size;// MAX size of the array
int count;// current number of elements in the dynamic array
protected:
int *intptr;// Our int pointer
};
list.cpp implementation file:
#include "list.h" // Include our Class defintion
#include <iostream>
using namespace std;
// CONSTRUCTOR
List::List() {
size = 2; // initial size of array
count = 0;
intptr = new int[size]; // Start off 2 integers sized array
}
// DECONSTRUCTOR
List::~List() {
delete[] intptr; // free allocated memory
}
// Copy constructor
List::List(const List& value) {
size = value.size;
cout << "Copy con size : " << size << endl;
count = value.count;
cout << "Compy count : " << count << endl;
if (count < size) {
intptr = new int[size]; // Allocate new data
} else {
intptr = new int[size + 2]; // Allocate new data
}
for (int index = 0; index < count; index++) {
intptr[index] = value.intptr[index];
}
size = size + 2;
delete[] intptr;
intptr = value.intptr;
}
void List::Insert(const int value) {
// do we have room?
if (count < size) {
intptr[count] = value;
} else { // if not we need to add more elements to array
intptr[count] = value; // DEEP copy invoked with copy constructor
}
cout << "SIZE: " << size << endl;
cout << "COUNT" << count << endl;
count++; // Increase items added in array
}
void List::display() const {
for (int i = 0; i < count; i++)
cout << intptr[i] << endl;
}
main.cpp tester
#include <iostream>
#include "list.h"
int main()
{
List mylist;
mylist.Insert(5);
mylist.Insert(6);
mylist.Insert(2);
mylist.Insert(8);
mylist.Insert(4);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.display();
system("PAUSE");
return 0;
}
回答1:
You are not managing the array correctly, especially in your Insert()
method. Try this instead:
#include "list.h" // Include our Class defintion
#include <iostream>
// CONSTRUCTOR
List::List()
{
intptr = new int[2];
size = 2;
count = 0;
std::cout << "Initial size : " << size << " count : " << count << std::endl;
}
// DECONSTRUCTOR
List::~List()
{
delete [] intptr; // free allocated memory
}
// Copy constructor
List::List(const List& value)
{
intptr = new int[value.size]; // Allocate new data
size = value.size;
count = value.count;
for(int index = 0; index < count; ++index)
intptr[index] = value.intptr[index];
std::cout << "Copy size : " << size << " count : " << count << std::endl;
}
void List::Insert(const int value)
{
if (count == size)
{
int *newintptr = new int[size+2];
for(int index = 0; index < size; ++index)
newintptr[index] = intptr[index];
delete[] intptr;
intptr = newintptr;
size += 2;
}
intptr[count] = value;
++count;
std::cout << "New size : " << size << " count : " << count << std::endl;
}
void List::display() const
{
for(int i = 0; i < count; i++)
std::cout << intptr[i] << std::endl;
}
.
#include <iostream>
#include "list.h"
int main()
{
List mylist;
mylist.Insert(5);
mylist.Insert(6);
mylist.Insert(2);
mylist.Insert(8);
mylist.Insert(4);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.display();
system("PAUSE");
List mylist2(myList); // copy construct a new list
mylist2.display();
system("PAUSE");
return 0;
}
With that said, you really should use std::vector
instead, eg:
#include <iostream>
#include <vector>
#include <algorithm>
void displayValue(int value)
{
std::cout << value << std::endl;
}
int main()
{
std::vector<int> mylist;
mylist.push_back(5);
mylist.push_back(6);
mylist.push_back(2);
mylist.push_back(8);
mylist.push_back(4);
mylist.push_back(5);
mylist.push_back(9);
mylist.push_back(8);
mylist.push_back(5);
mylist.push_back(9);
mylist.push_back(8);
mylist.push_back(5);
mylist.push_back(9);
mylist.push_back(8);
mylist.push_back(5);
mylist.push_back(9);
std::for_each(mylist.begin(), myList.end(), displayValue);
system("PAUSE");
std::vector<int> myList2(myList);
std::for_each(mylist2.begin(), myList2.end(), displayValue);
system("PAUSE");
return 0;
}
To take it a step further, if you want to keep using your custom List
class, at least use std::vector
inside of it:
#include <vector>
class List
{
public:
// DEFAULT Constructor
List();
//Modification methods
void Insert(const int);
// User ACCESS methods
void display(void) const;
protected:
std::vector<int> intvec;
};
.
#include "list.h" // Include our Class defintion
#include <iostream>
// CONSTRUCTOR
List::List()
{
intvec.reserve(2);
std::cout << "Initial size : " << intvec.capacity() << " count : " << intvec.size() << std::endl;
}
// Copy constructor
List::List(const List& value)
{
intvec = value.intvec;
std::cout << "Copy size : " << invec.capacity() << " count : " << intvec.size() << std::endl;
}
void List::Insert(const int value)
{
intvec.push_back(value);
std::cout << "New size : " << intvec.capacity() << " count : " << intvec.size() << std::endl;
}
void List::display() const
{
for(std::vector<int>::const_iterator iter = intvec.begin(), end = intvec.end(); iter != end; ++iter)
std::cout << *iter << std::endl;
}
.
#include <iostream>
#include "list.h"
int main()
{
List mylist;
mylist.Insert(5);
mylist.Insert(6);
mylist.Insert(2);
mylist.Insert(8);
mylist.Insert(4);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.Insert(8);
mylist.Insert(5);
mylist.Insert(9);
mylist.display();
system("PAUSE");
List mylist2(myList); // copy construct a new list
mylist2.display();
system("PAUSE");
return 0;
}
回答2:
Your List::Insert(const int value)
method doesn't call the List
copy constructor at all, it only writes inside the intptr
array. When count
gets bigger than size
, you write outside of the array and that's why you have errors.
You should move what you do in the copy constructor to the Insert
method directly.
回答3:
The reason for copy-constructor is to create a new object from existing one, but look at you copy-constructor, what are you doing there?
/* initialize my size and count, from value */
size = value.size;
count = value.count;
/* Check count and size */
if( count == size ) /* if other is full */
size += 2;
/* copy content from value.intptr into this->intptr */
//if (count < size)
// intptr = new int[size]; // Allocate new data
//else
// intptr = new int[size + 2]; // Allocate new data
intptr = new int[size]; /* Allocate my buffer */
/* It's better to use std::copy in place of a hand written loop */
//for(int index = 0; index < count; index++)
// intptr[index] = value.intptr[index];
std::copy( value.intptr, value.intptr + value.count, intptr );
/* why you increase your size here?? shouldn't this indicate size of intptr? */
//size = size + 2;
/* After creating a new buffer and putting data into it, you destroy the buffer
and set your buffer equal to buffer of value? why? if value destroyed it will
destroy its intptr and your intptr point to a deleted memory
*/
//delete [] intptr;
// intptr = value.intptr;
Now look at your insert
method:
if(count < size) // do we have room?
{
intptr[count] = value;
}
else // if not we need to add more elements to array
{
/* As you already checked you do not have enough room to insert data to intptr
so why you do it here? shouldn't you first allocate a new buffer and then
copy data to it?
In comment you say DEEP copy with copy-constructor, which copy constructor
you expect to called here? you are assigning an int to another int, so where
is copy constructor?
*/
// intptr[count] = value; // DEEP copy invoked with copy constructor
int* tmp = new int[size + 2];
std::copy( intptr, intptr + size, tmp );
delete[] intptr;
intptr = tmp;
size += 2;
intptr[count] = value;
}
count++; // Increase items added in array
回答4:
Use std::vector. It already does all of this, and does it safer and faster than your code will.
来源:https://stackoverflow.com/questions/12982730/dynamic-list-of-integers-in-c