Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ program randomly stops

  1. One time, my program runs and shows expected output, and sometime it don’t (it compiles without any errors). Try-Catch doesen’t seem to affect on this random output.

  2. v3f is a simple class that holds 3 floats: x,y,z and some basic math operations on them (all of them work perfectly fine)

v3f calculate_normal(v3f a, v3f b, v3f c);
  1. "calculate_normal" is just a simple multiplication and subtraction function that returns v3f, AND when it "decides" to work it gives expected output.
int main()
{
    lv::v3f c(-0.5, -0.5, 0);
    lv::v3f b(0, .5f, 0);
    lv::v3f a(0.5, -0.5, 0);
    /* if I add here 
          v3f d = a - b;
    */ it works !
    lv::v3f normal;

    std::cout << "1\n";
    normal = lv::calculate_normal(a, b, c);
    std::cout << "2\n";
    std::cout << normal.x << " " << normal.y << " " << normal.z << std::endl;
    std::cout << "3\n";

    return 0;
}

I cout’ed 1, 2 and 3 to see when program breaks and it’s sometimes outputting all:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

output:
1
2
0 0 1
3

And sometimes it stops on "1" (before calculating normal)

output:
1
// - - - - - - - - - - - - - - "Vector3.h"
#ifndef _LV_VECTOR_3_H_
#define _LV_VECTOR_3_H_

namespace lv{



template <class T>
class Vector3
{
    public:
        T x, y, z;

        Vector3(T _x = 0, T _y = 0, T _z = 0) : x(_x), y(_y), z(_z){}

        float length()
        {
            return sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
        }

        Vector3<T> normal()
        {
            float l = length();
            return Vector3<T>(x/l, y/l, z/l); 
        }

        void normalize()
        {
            float l = length();
            x /= l;
            y /= l;
            z /= l;
        }

        Vector3<T>& operator += (const Vector3<T>& o)
        {
            this->x += o.x;
            this->y += o.y;
            this->z += o.z;
            return *this;
        }

        Vector3<T>& operator -= (const Vector3<T>& o)
        {
            this->x -= o.x;
            this->y -= o.y;
            this->z -= o.z;
            return *this;
        }

        Vector3<T>& operator *= (const Vector3<T>& o)
        {
            this->x *= o.x;
            this->y *= o.y;
            this->z *= o.z;
            return *this;
        }
        
        Vector3<T>& operator /= (const Vector3<T>& o)
        {
            this->x /= o.x;
            this->y /= o.y;
            this->z /= o.z;
            return *this;
        }

        friend Vector3<T>& operator + (const Vector3<T>& o, const Vector3<T> p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x + p.x;
            tmp->y = o.y + p.y;
            tmp->z = o.z + p.z;
            return *tmp;
        }

        friend Vector3<T>& operator - (const Vector3<T>& o, const Vector3<T> p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x - p.x;
            tmp->y = o.y - p.y;
            tmp->z = o.z - p.z;
            return *tmp;
        }

        friend Vector3<T>& operator / (const Vector3<T>& o, const Vector3<T> p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x / p.x;
            tmp->y = o.y / p.y;
            tmp->y = o.z / p.z;
            return *tmp;
        }

        friend Vector3<T>& operator * (const Vector3<T>& o, const Vector3<T> p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x * p.x;
            tmp->y = o.y * p.y;
            tmp->z = o.z * p.z;
            return *tmp;
        }

        friend Vector3<T>& operator * (const Vector3<T>&o, float p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x * p;
            tmp->y = o.y * p;
            tmp->z = o.z * p;
            return *tmp;
        }

        friend Vector3<T>& operator / (const Vector3<T>&o, float p)
        {
            Vector3<T>* tmp;
            tmp->x = o.x / p;
            tmp->y = o.y / p;
            tmp->z = o.z / p;
            return *tmp;
        }
};



#define v3f  Vector3<float>
#define v3i  Vector3<int>
#define v3d  Vector3<double>
#define v3ui Vector3<unsigned int>



}; // L V

#endif



//  - - - - - - - - - - - - - - "Vector.h"
#ifndef _LV_VECTOR_H_
#define _LV_VECTOR_H_

#include "Vector2.h"
#include "Vector3.h"
#include "Vector4.h"

#endif




//  - - - - - - - - - - - - - - "Utils.h"
#ifndef _LV_UTILS_H_
#define _LV_UTILS_H_

#include "Vector.h"

namespace lv {



v3f calculate_normal(v3f a, v3f b, v3f c)
{
    std::cout << "a\n";
    v3f u = b - a;
    v3f v = c - a;
    std::cout << "b\n";

    v3f n;
    n.x = u.y * v.z - u.z * v.y;
    n.y = u.z * v.x - u.x * v.z;
    n.z = u.x * v.y - u.y * v.x;
    std::cout << "c\n";

    return n;
}



}; // L V

#endif




// - - - - - - - - - - - - - - "main.cpp"
#include <iostream>
#include "Liviana/Math/Utils.h"

int main()
{

    lv::v3f c(-0.5, -0.5, 0);
    lv::v3f b(0, .5f, 0);
    lv::v3f a(0.5, -0.5, 0);
    lv::v3f normal;

    std::cout << "1\n";

    normal = lv::calculate_normal(a, b, c);
    
    std::cout << "2\n";
    std::cout << normal.x << " " << normal.y << " " << normal.z << std::endl;
    std::cout << "3\n";


    return 0;
}

>Solution :

Only the mutating operators should return references. The other operators should return values.

OK:

Vector3<T>& operator += (const Vector3<T>& o)

Not ok:

friend Vector3<T>& operator + (const Vector3<T>& o, const Vector3<T> p)

The above is not ok, because…what are you going to return a reference to? 1 + 2 is neither 1 nor 2. It’s something else. You’ll need storage for the result (a Vector3) and you’ll need to return it by value.

friend Vector3<T> operator + (const Vector3<T>& o, const Vector3<T> p) {
    Vector3<T> tmp;
    tmp.x = o.x + p.x;
    tmp.y = o.y + p.y;
    tmp.z = o.z + p.z;
    return tmp;
}

Note the & is gone from the return type.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading