Losing Float Object Data in array

Hello. I have some experience with Java, but I'm finding that programming in an object-oriented sense in C++ is a world different, and I'm a bit lost among all these different pointers and other information.

In particular I'm having some problems keeping a few float values in place in a custom object, Sphere. I have a method called setPosition that should change some values in a particular Sphere object in an array of Sphere objects, but somehow using this method seems to alter the information in other objects in the array! After several hours of experimenting, I'm still pretty stumped and am tempted to think I'm getting pointers tangled up somehow.

Here is the source code:

Sphere.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <math.h>
#include <vector>
#include <Inventor/SbLinear.h>
#include <Inventor/actions/SoGetMatrixAction.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoLight.h>
#include <Inventor/nodes/SoPointLight.h>
using namespace std;
#include "OSUInventor.h"
#include "Camera.h"

class Sphere {
	SbVec3f pos;
	SbVec3f color;
	bool on;
public:
	Sphere ();
	//Sphere (SbVec3f);
	//Sphere (SbVec3f,SbVec3f);
	void setPosition(SbVec3f);
	void setOn();
	void setOff();
	SbVec3f getPosition();
	void dumpPosition();
	};

// constructor using position as input
Sphere::Sphere () {
	cout << "Sphere object:  Constructing a new sphere at 0,0,0."  << endl;
	float x = 0;
	float y = 0;
	float z = 0;
	pos = SbVec3f(x,y,z);
	color[0]=255;
	color[1]=255;
	color[2]=255;

	}

// constructor using position as input
//Sphere::Sphere (SbVec3f posInput) {
	//cout << "Sphere object:  Constructing a new sphere at specified input."  << endl;
	//pos = posInput;
	//color[0]=255;
	//color[1]=255;
	//color[2]=255;
	//}

// constructor using position as input
//Sphere::Sphere (SbVec3f posInput, SbVec3f colorInput) {
	//cout << "Sphere object:  Constructing a new sphere at specified input, with color!"  << endl;
	//pos = posInput;
	//color[0]=colorInput[0];
	//color[1]=colorInput[1];
	//color[2]=colorInput[2];
	//}

void Sphere::setPosition (SbVec3f posInput) {
	pos = posInput;
	}

void Sphere::setOn () {
	on = true;
	}

void Sphere::setOff () {
	on = false;
	}

SbVec3f Sphere::getPosition () {
	return pos;
	}

void Sphere::dumpPosition () {
	cout << "Sphere object:  Dumping position."  << endl;
	cout << "X:  " << pos[0] << endl;
	cout << "Y:  " << pos[1] << endl;
	cout << "Z:  " << pos[2] << endl;
	}


And I'm trying to manipulate my items here, in this snippet from main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Sphere sphereArray[3];
	int sphereArrayIndex = 0;

	sphereArray[0].dumpPosition();
			sphereArray[1].dumpPosition();
			sphereArray[2].dumpPosition();
		   cout << "-------------------" << endl;

			// SPHERE CONSTRUCTOR
			float x0 = 1;
			float y0 = 1;
			float z0 = 1;
			SbVec3f coord = SbVec3f(x0,y0,z0);
			sphereArray[0].setPosition(coord);
			sphereArray[1].setPosition(coord);
			sphereArray[2].setPosition(coord);

			sphereArray[0].dumpPosition();
			sphereArray[1].dumpPosition();
			sphereArray[2].dumpPosition();
		   cout << "-------------------" << endl;

			float x1 = 2;
			float y1 = 2;
			float z1 = 2;
			SbVec3f coord2 = SbVec3f(x1,y1,z1);
			//sphereArray[1].setPosition(coord2);

			sphereArray[0].dumpPosition();
			sphereArray[1].dumpPosition();
			sphereArray[2].dumpPosition();
		   cout << "-------------------" << endl;


My first "dump" shows that each Sphere still holds position 0,0,0. However, when I dump the values after calling the first setPosition, the values end up like this:

1
2
3
4
5
6
7
8
9
10
11
12
Sphere object:  Dumping position.
X:  0
Y:  2.277795e-041
Z:  2.277795e-041
Sphere object:  Dumping position.
X:  0
Y:  -8.82818e-044
Z:  -8.82818e-044
Sphere object:  Dumping position.
X:  1
Y:  1
Z:  1


The first two sphere objects should also all have 1,1,1 values, but they have these values that seem kind of like floating point errors. And the attempt to put 2,2,2 doesn't seem to work any better.

Is anyone able to point out what I might be doing wrong here? Thanks!
Any chance SbVec3f is a wrapper class for an array of 3 values? I think the problem is that you're trying to copy arrays rather than "three values". In java these are the same, but here they aren't.

In short, in C(++), arrays "are" pointers. An array "myArray[3]" is actually just a pointer to the first element of myArray. Accessing "myArray[2]" just takes two steps forward in the memory, starting from the first element.

Your copy operator (either you made one yourself, or the compiler made a generic one) just copies each element. For regular types, this is no problem. For arrays, however, it copies the pointer, not the data. To get around it, you have to override your copy operator to do a full copy that iterates over the elements of the array and copies those.
Thanks for your help.

Accessing "myArray[2]" just takes two steps forward in the memory, starting from the first element.


When you have an array of integers, this seem easy enough. But when you have custom objects that might need a lot more area in memory before the next 'element', I take it this will no longer work, and accessing myArray[2] will take you to some spot in memory that could, presumably, belong to some member data of the first element? Or is this still able to pick out the first location of memory unique to element 2?

If the first case, would the solution be to create an array of pointers, where each element in the array points to a specific object in an array of objects? I've seen this done in various tutorials but hoped I wouldn't need to do it.

So, as I understand it, when I have a method like this:

1
2
3
4
5
6
7
8
void Sphere::setPosition (SbVec3f posInput) {
	x=posInput[0];
	y=posInput[1];
	z=posInput[2];

        pos = Sbvec3f(x,y,z);

	}


This should work by storing the individual x,y,z values taken from posInput into the member variable. But doing something like this:

1
2
3
4
5
void Sphere::setPosition (SbVec3f posInput) {

        pos = posInput;

	}


Creates that copy-over problem, copying the pointer and not the data. Is this assumption correct?
Looks like there's something wrong with 'SbVec3f'. what is it?
SbVec3f is a 3-member vector used in the Coin3d libraries. This is its documentation:

http://doc.coin3d.org/Coin/classSbVec3f.html

I'm also getting a funny little "Overloaded member function not found in 'Sphere'" error. My code is as such:

1
2
3
4
5
6
7
8
9
10
11
class Sphere {

public:
	Sphere::Sphere ();
	void setPosition (SbVec3f posInput);
	void setPosition(float a, float b, float c);
	void dumpPosition ();
	void dumpFloatsPosition ();
	SbVec3f getPosition ();

	};


1
2
3
4
5
6
7
8
9
10
11
void Sphere::setPosition (SbVec3f posInput) {
	x=posInput[0];
	y=posInput[1];
	z=posInput[2];
	}

void Sphere::setPosition(float a, float b, float c)	{
	x=a;
	y=b;
	z=c;
	}


I'm not sure why it isn't so fond of the newer overridden method that uses the three floats...
I solved the problem. Turns out the problem was originating from forgetting to include the member variables in the Sphere.h file--C++ didn't tell me I was doing anything wrong for reasons I'm sure make sense when you get down to optimization and all.

The code that made the difference was this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Sphere {

public:

	// member variables
	float xPos;
	float yPos;
	float zPos;
	SbVec3f vecPos;
	float xDiff;
	float yDiff;
	float zDiff;
	SbVec3f vecDiff;

	 //constructor
	Sphere::Sphere ();

	// public members
	void setPosition (SbVec3f posInput);
	void setPosition(float a, float b, float c);
	void setRadius(float rad);
	void dumpPosition ();
	void dumpFloatsPosition ();
	SbVec3f getPosition ();

	};
Topic archived. No new replies allowed.