C++程序随机停止

  • 本文关键字:随机 程序 C++ c++
  • 更新时间 :
  • 英文 :

  1. 有一次,我的程序运行并显示预期的输出,有时却没有(它编译时没有任何错误(。Try-Catch似乎不会影响这个随机输出。

  2. v3f是一个简单的类,它包含3个浮点:x、y、z和一些基本的数学运算(所有这些运算都非常好(

v3f calculate_normal(v3f a, v3f b, v3f c);
  1. "calculate_normal";只是一个简单的乘法和减法函数;决定";为了工作,它给出了预期的输出
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 << "1n";
normal = lv::calculate_normal(a, b, c);
std::cout << "2n";
std::cout << normal.x << " " << normal.y << " " << normal.z << std::endl;
std::cout << "3n";
return 0;
}

我定制了1、2和3,看看程序何时中断,有时它会输出所有内容:

output:
1
2
0 0 1
3

有时它会停在";1〃;(在计算正常值之前(

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 << "an";
v3f u = b - a;
v3f v = c - a;
std::cout << "bn";
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 << "cn";
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 << "1n";
normal = lv::calculate_normal(a, b, c);

std::cout << "2n";
std::cout << normal.x << " " << normal.y << " " << normal.z << std::endl;
std::cout << "3n";

return 0;
}

只有变异运算符应该返回引用。其他运算符应返回值。

好的:

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

不好:

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

以上不好,因为。。。你打算返回什么参考?1+2既不是1也不是2。这是另一回事。您需要存储结果(Vector3(,并且需要按值返回。

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

请注意,返回类型中没有&

您正在取消引用每个算术运算符中未初始化的指针:

Vector3<T>& operator + (const Vector3<T>& o, const Vector3<T> p)
Vector3<T>* tmp; // Where does tmp point to?
tmp->x = o.x + p.x;
tmp->y = o.y + p.y;
tmp->z = o.z + p.z;
return *tmp;
}

取消引用一个在其生存期内没有指向有效对象的指针是"未定义行为",它会导致程序无效,并且可以执行任何操作。

您应该避免使用指针。只需使用一个普通的局部变量并按值返回即可:

Vector3<T> operator + (const Vector3<T>& o, const Vector3<T> p)
Vector3<T> tmp; // No more pointer
tmp.x = o.x + p.x;
tmp.y = o.y + p.y;
tmp.z = o.z + p.z;
return tmp;
}

最新更新