I have a class that contains an array of another class called Sphere. Right now i am not sure why one part of code is generating an error.
.H file
sphere* list;
int listlen;
void add(sphere x);
sarray operator +(const sarray& arrayone);
.Cpp
sarray::sarray()
{
listlen = 0;
list = new sphere[200000];
}
sarray::~sarray()
{
delete [] this->list;
}
void sarray::add(sphere x) // Function for adding spheres to the list.
{
listlen++;
list[listlen-1] = x;
}
void sarray::operator = (const sarray& arrayone)
{
this -> list = NULL;
for(int i = 0; i < arrayone.listlen; i++)
{
this -> add(arrayone.list[i]);
}
}
sarray sarray::operator +(const sarray& arrayone)
{
sarray temparray;
for(int i = 0; i < arrayone.listlen; i++) // add all the elements from the first array to the temporary one
{
//sphere temp = arrayone.list[i];
temparray.add(arrayone.list[i]);
}
for(int j = 0; j < this -> listlen; j++)// add all the elements from the second array to the temporary one
{
temparray.add(list[j]);
}
return temparray;
}
The sphere class got a member variable called "Radius"
which when i try to compare like this
float a = 10;
for(int i=0; i > this->listlen;i++)
if(this->list[i].Radius > a) //<-- Can read the values
Works fine, but when change this part of the code
float a = 10;
sarray temparray = arrayone + *this;
for(int i = 0; i < temparray.listlen; i++)
if(temparray.list[i].radius > a) // Error comes here!
"Unhandled exception at 0x00138503: Access violation reading location"
while this doesent. I guess the problem is in the Add/operator function but i cant find it.
The following part looks problematic:
void sarray::add(sphere x) // Function for adding spheres to the list.
{
list[listlen-1] = x;
}
you should rather have something like this
void sarray::add(sphere x) // Function for adding spheres to the list.
{
list[listlen++] = x;
}
Also you should better have some error checking in add method.
OK, having looked at the destructor, you have a pointer to sphere in your sarray and has a destructor to destroy the pointer. This is all good except you haven't defined your own copy constructor which means the default copy constructor is used. In the function operator+ where you return temparray, a copy of the local copy is returned. The default copy constructor is called to create the copy. Then the local one will be destructed. Now the returned sarray copy's list will point to invalid data. You need to define your own copy constructor to make a deep copy of the list pointer.
Related
I'm having a lot of issues with creating a dynamic array containing objects.
As I've understood it, because my array is handling objects, the class stored in the array must have a copy constructor or an assignment operator so that all will be copied properly.
I've successfully created this program with a normal array of defined size. Now I have a lot of problems creating the same program with a dynamic array.
Class 1 The objects to be stored:
class objToBeStored{
private:
string dataToBeStored;
int sizeOfArray;
string *storedArray;
public:
objToBeStored(); //empty constructor
objToBeStored& operator =(const objToBeStored& o); // assignment operator
~objToBeStored(); //destructor (no code inside);
bool getData(istream &stream);
//.....other methods to do stuff
};
objToBeStored::objToBeStored(){
//empty
}
objToBeStored& objToBeStored::operator=(const objToBeStored& o){
if(this != o){
dataToBeStored = o.dataToBeStored;
for (int i = 0; i < sizeOfArray; i++){
storedArray[i] = o.storedArray[i];
}
}
return *this;
}
void objToBeStored::getData(istream &stream){
stream >> dataToBeStored >> sizeOfArray;
storedArray = new string[sizeOfArray];
for(int i = 0; i < sizeOfArray; i++){
stream >> storedArray[i];
}
return !stream.eof();
}
//.....other methods to do stuff
Class 2 contains the dynamic array that stores the above objects. Everything is working,except how I declared my dynamic array and the functions handling it. Therefore I will write this code below:
class storageArrayClass{
private:
storageArrayClass *store;
storageArrayClass *storptr;
int numberOfstored;
public:
storageArrayClass(); //empty constructor
~storageArrayClass();
void addElm(objToBeStored & o);
//other functions to do stuff
};
storageArrayClass::storageArrayClass(){ //constructor
numberOfstored = 0;
}
storageArrayClass::~storageArrayClass(){
}
void storageArrayClass(istream &stream) {
objToBeStored o;
o.getData(stream);
if(numberOfstored == 0){ //check it this is the first element
store = new objToBeStored[1]; //create a new array with length 1
store[(numberOfstored] = o; //store object
}else{
objToBeStored tmpStore = new objToBeStored[(numberOfstored+1]; //create a temp. array with 1 more position
for(int i=0; i < numberOfstored; i++){
tmpStore[i] = store[i]; //copy original array to the temp. array
storptr = &tmpStore[i]; // increment a point
}
storptr++; //increment pointer to last position
*storptr = o; //store object in last position
delete[] store; //delete the original array
store = new objToBeStored[(numberOfstored+1]; //create a new original array
store = tmpStore;//copy temp. array
}
}
I manage to add 3 objects to my dynamic array before I get the following error:
Process returned -1073741819 (0xC0000005) execution time : 5.059 s
Please help. I've read countless threads here, but I cannot get it to work.
I am not sure where I am going wrong with this.
I have a Movie.h with all the data members and constructors destructors and copy constructors needed but I have a feeling it's failing at my assignment operator someone, please help
Movie& Movie::operator=(const Movie& _assign) {
// Self-assignment check
if (this == &_assign)
return *this;
// Shallow copy non-dynamic data members
mRuntime = _assign.mRuntime;
// Deep copy appropriate data members
mTitle = new char[strlen(_assign.mTitle) + 1];
strcpy_s(mTitle, strlen(_assign.mTitle) + 1, _assign.mTitle);
// Deep copy the reviews
SetStars(_assign.mStars, mNumReviews);
return *this;
}
void Movie::SetStars(const int* _stars, int _numReviews) {
// Allocate array and deep copy
mStars = new int[_numReviews];
for (int i = 0; i <= _numReviews; ++i) {
// Cap reviews between 1-10
if (_stars[i] > 10)
{
mStars[i] = 10;
}
else if (_stars[i] < 0)
{
mStars[i] = 0;
}
else
{
mStars[i] = _stars[i];
}
}
// Set the number of reviews
mNumReviews = _numReviews;
}
The problem happens here:
mStars = new int[_numReviews];
for (int i = 0; i <= _numReviews; ++i) {
Specifically here:
i <= _numReview // this causes you to go out of bounds
changing it to:
i < _numReview
resolves the issue
You are allocating _numReview items. C++ has 0-based array indexing. Elements will go from 0 to _numReview - 1
Please consider using std::string and std::vector instead of c-style arrays.
I am trying to return the object LorentzBoostedVector of the class FourVector from this function, which is a member of FourVector. The class is derived from a Vector general class, and contains a pointer to an array of size 4 containing data called elementData. Here I call the default constructor of FourVector and then set it's elementData components using the formulae in the code. I then try to return the object by value.
The code works correctly and creates the FourVector (I have checked this) but the program stops working when I try to return the LorentzBoostedVector. Any idea why this might be? I have a feeling it is something to do with destructors being called before the object is returned but I don't know how to fix this.
FourVector LorentzBoost(ThreeVector& betaVector) {
double gamma = betaVector.gamma();
FourVector LorentzBoostedVector;
ThreeVector r(elementData[1], elementData[2], elementData[3]);
LorentzBoostedVector[0] = gamma*(elementData[0] - betaVector.dotProduct(r));
for (int i = 1; i < 4; i++) {
LorentzBoostedVector[i] = r[i-1] + (((gamma - 1)*betaVector.dotProduct(r) / betaVector.dotProduct(betaVector)) - gamma*elementData[0])*betaVector[i - 1];
}
return LorentzBoostedVector;
}
The constructors and destructors of the FourVector class are
//default constructor for FourVector
FourVector() {
delete[] elementData;
numberOfDimensions = 4;
elementData = new double[numberOfDimensions];
}
//parameterised constructor for FourVector
FourVector(double ct, double x, double y, double z) {
delete[] elementData;
numberOfDimensions = 4;
elementData = new double[4];
elementData[0] = ct; elementData[1] = x;elementData[2] = y;elementData[3] = 1;
}
~FourVector() {
cout << "Four Vector Destructor Called" << endl;
delete[] elementData;
}
I've got some project for my University and I need to perform converting some data from file to matrix representation.
The main problem is that after returning form "returnNeighbours(int node)" destructor is called on neighbours object(as I concluded from running gdb).
I know that destructor is always called when local variable, in function, is initialized, but neihbours is a class member. I won't post everything, because it's not necessary I think. I've got some structures listed below.
representation.cpp
NodeContainer::NodeContainer(){ size = 0; array = nullptr; }
NodeContainer::~NodeContainer(){ size = 0; delete[] array; }
void NodeContainer::allocateMemoryAndSetSize(int n){ size = n; array = new int[size]; }
void MatrixRep::convertDataToMatrixRep(int** array)
{
for(int i = 0 ; i != size; i++)
for(int j = 0; j != size; j++)
matrix[i][j] = array[i][j];
}
NodeContainer MatrixRep::returnNeighbours(int node)
{
deleteNeighboursIfAny();
if(!checkIfNotBeyondMatrix(node))
return neighbours;
neighbours.allocateMemoryAndSetSize(countNeighbours(node));
for(int i = 0, j = 0; i < size; i++)
if(matrix[node-1][i] != 0)
{
neighbours.array[j] = matrix[node-1][i];
j++;
}
return neighbours;
}
void MatrixRep::deleteNeighboursIfAny(){ if(neighbours.array) neighbours.~NodeContainer(); }
bool MatrixRep::checkIfNotBeyondMatrix(int node)
{
if(node == 0 || node > size)
{
std::cerr<<"There is no such a node!\n";
return false;
}
else
return true;
}
int MatrixRep::countNeighbours(int node)
{
int count_non_zero = 0;
for(int i = 0; i != size; i++)
if(matrix[node-1][i] != 0)
count_non_zero++;
return count_non_zero;
}
representation.h
struct NodeContainer
{
int size;
int* array;
NodeContainer();
~NodeContainer();
void allocateMemoryAndSetSize(int);
};
class MatrixRep
{
int size;
NodeContainer neighbours;
int** matrix;
public:
MatrixRep(int);
~MatrixRep();
void convertDataToMatrixRep(int**);
NodeContainer returnNeighbours(int);
void deleteNeighboursIfAny();
bool checkIfNotBeyondMatrix(int);
int countNeighbours(int);
void setupMatrix();
void deleteMatrix();
};
If you would like to return a copy of NodeContainer, you must implement a copy constructor and assignment operator for it. If you're using a C++11 conformant compiler it will also be good to also implement a move constructor and move assignment operator as well.
On the other hand, if you would like to not create a copy, you must either return a pointer or a reference to the member. You could also make the member a std::shared_ptr, which you may return in this case.
However, in your current implementation you're actually returning a shallow copy of NodeContainer. Once your copy goes out of scope its destructor is called, which deallocates its memory, which in this case is the original memory of your member, effectively making your member invalid. The implementation is not good as it is. So, depending on your goal, either implement the first advised solution, or the second.
Hey basically Im trying to store a "solution" and create a vector of these. The problem I'm having is with initialization. Heres my class for reference
class Solution
{
private:
// boost::thread m_Thread;
int itt_found;
int dim;
pfn_fitness f;
double value;
std::vector<double> x;
public:
Solution(size_t size, int funcNo) : itt_found(0), x(size, 0.0), value(0.0), dim(30), f(Eval_Functions[funcNo])
{
for (int i = 1; i < (int) size; i++) {
x[i] = ((double)rand()/((double)RAND_MAX))*maxs[funcNo];
}
}
Solution() : itt_found(0), x(31, 0.0), value(0.0), dim(30), f(Eval_Functions[1])
{
for (int i = 1; i < 31; i++) {
x[i] = ((double)rand()/((double)RAND_MAX))*maxs[1];
}
}
Solution operator= (Solution S)
{
x = S.GetX();
itt_found = S.GetIttFound();
dim = S.GetDim();
f = S.GetFunc();
value = S.GetValue();
return *this;
}
void start()
{
value = f (dim, x);
}
/* plus additional getter/setter methods*/
}
Solution S(30, 1) or Solution(2, 5) work and initalizes everything, but I need X of these solution objects. std::vector<Solution> Parents(X) will create X solutions with the default constructor and i want to construct using the (int, int) constructor. Is there any easy(one liner?) way to do this? Or would i have to do something like:
size_t numparents = 10;
vector<Solution> Parents;
Parents.reserve(numparents);
for (int i = 0; i<(int)numparents; i++) {
Solution S(31, 0);
Parents.push_back(S);
}
the example I gave as a comment uses copy constructor to create new objects.
You can do the following:
// override copy constructor
Solution(const Solution &solution) {
... copy from another solution
}
however be careful, as you no longer going to have exact object copy/construct if you introduce random generation in your copy constructor, i.e. Solution y = x; y != x
your best solution is something like you already have in my opinion
I have used the Boost assignment library for tasks like this. You may find it useful....