Pointer as parameter is null


In my raytracer-project I have the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bool hitObjects(Ray &ray, std::vector<Object *> &objects, Vector3& normal, Material *mat) {
	double tmin = K_HUGE_VALUE;
	double t;
	bool hit;
	for(int i = 0; i < objects.size(); i++) {
		if (objects.at(i)->mesh->hit(ray, t, normal) && t < tmin) {
			tmin = t;
			mat = objects.at(i)->material;
			hit = true;
		}
		else {
			hit = false;
		}
	}
	if (hit && mat == NULL) {
		std::cout << "Object was hit, but material is still NULL\n";
	}
	return hit;
}


This is then being called by

1
2
3
4
if (hitObjects(ray, objects, normal, mat)) {
	if (mat == NULL) {
		std::cout << "Material pointer is null\n";
	}


When I try to run this, I only get the message "Material pointer is null". So, somehow the pointer is null after the hitObjects-function is called, even though it isn't inside that function. Does anyone know what I'm doing wrong?


Fafner
That's weird, but we need to see the declaration of Material and the declaration of mat in the caller.
Sure.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Material {
public:
	virtual Vector3 shade(std::vector<Light*> lights, Vector3& normal) = 0;
};

class PhongMaterial : public Material {
private:
	Vector3 specular_reflectance;
	Vector3 diffuse_reflectance;
	Vector3 ambient_reflectance;
	float specular_exponent;

public:
	PhongMaterial(Vector3 s = 0, Vector3 d = 0, Vector3 a = 0, float e = 0.0) :
		specular_reflectance(s), diffuse_reflectance(d),
		ambient_reflectance(a), specular_exponent(e) {}

	Vector3 shade(std::vector<Light*> lights, Vector3& normal) {
		return Vector3(1.0, 0.0, 0.0); //TODO
	}
};


I forgot to add, mat is just a pointer declared right before hitObjects is called, like so

1
2
3
4
5
6
Material *mat = NULL;
if (hitObjects(ray, objects, normal, mat)) {
	if (mat == NULL) {
		std::cout << "Material pointer is null\n";
	}
...
The Object-class is just super-simple, like this

1
2
3
4
5
6
7
class Object {
public:
	Geometry *mesh;
	Material *material;

	Object(Geometry *m, Material *mat) : mesh(m), material(mat) {}
};
The parameter mat is the copy of the pointer. Any change isn't propagated to the caller. If you want that you either provide pointer to the pointer Material ** mat or refernce Material *& mat
Wow, thanks! Can't say I fully understand why that works yet, but it does! :P Thank you:)
Can't say I fully understand why that works yet, but it does!
The keyword here is copy. You're passing the pointer by value hence you have a copy of the pointer. Modifing the copy [of the pointer] leaves the original [pointer] unchanged

You may read this:
http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value
Topic archived. No new replies allowed.