Program stops working on return of custom object from function - c++

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;
}

Related

Bad array new length error unhandled exception

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.

Creating multiple objects and passing parameters through constructor

I am trying to understand how to create multiple objects(20 in the current case) and pass parameter to the constructor as shown in the comments of the code. Unfortunately, I cannot pass parameters as well as have an array of objects at the same time.
I tried this as well to create the object convector con(100,200, construct(20)); but it didn't seem to give the desired result
#include <iostream>
class construct {
public:
int a, b;
// Default Constructor
construct(int x1,int x2)
{
a = x1;
b = x2;
}
int getX1(){
return a;
}
int getX2(){
return b;
}
};
int main(){
int p,q;
construct* con = new construct[20](100,200);
for (unsigned int i = 0; i < 20; i++) {
p=con[i]->getX1();
q=con[i]->getX2();
printf("%d %d \n",p,q);
}
delete con;
return 1;
}
Expected result would be 20 objects created.
Just use std::vector. Seriously, there's no reason not to.
std::vector<construct> con(20, {100, 200});
Yeah, for this you are likely to need placement new sadly (or use std::vector, and pass a newly constructed object as the second argument).
// call global new (effectively malloc, and will leave objects uninitialised)
construct* con = (construct*)::operator new (sizeof(construct) * 20);
// now call the ctor on each element using placement new
for(int i = 0; i < 20; ++i)
new (con + i) construct(100, 200);

Why does this code generate error?

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.

Passing Class with a Pointer Member

I have a simple matrix class which has a 2d integer pointer field in it. When I call following function multiple times, it gives me a glibc error on Linux machine. When I have "otherM.value = '\0';" add this line to the end of function, problem resolves. Could somebody explain me why I have this dangling pointer issue, although class is passed by copy, not by reference? Pointer members are passed by reference?
void matrix::sub(matrix otherM)
{
if(dimX!=otherM.dimX || dimY!=otherM.dimY)
return;
int** rowPtr = value;
int** otherMrowPtr = otherM.value;
for(int i=0;i<dimX;i++){
for(int j=0;j<dimY;j++){
(**rowPtr) = (**rowPtr) - (**otherMrowPtr);
(*rowPtr)++;
(*otherMrowPtr)++;
}
(*rowPtr)-=dimY;
(*otherMrowPtr)-=dimY;
rowPtr++;
otherMrowPtr++;
}
rowPtr = '\0';
otherMrowPtr = '\0';
otherM.value = '\0';
}
matrix::matrix(int x, int y){
dimX = x;
dimY = y;
// allocate here
value = new int*[dimX];
int** rowPtr = value;
for(int i=0;i<dimX;i++){
*rowPtr = new int[dimY];
rowPtr++;
}
}
matrix::~matrix(){
if(value!=NULL){
int** rowPtr = value;
for(int i=0;i<dimX;i++){
delete[] (*rowPtr);
rowPtr++;
}
rowPtr-=dimX;
delete[] rowPtr;
rowPtr = '\0';
}
value = '\0';
}
Did you implement copy constructor, assignment operator and destructor for your class? If not then go and implement those since you're managing a resource.

initializing a vector of custom class in c++

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....