C++ pointers within a struct

I have a problem.
I have a struct, "Figure", and one of its members, "vertices" is a pointer to another struct, "Point".
I have created an array of pointers to the data type struct "Figure"
Now I need to create an array of pointers to the data struct "Point", which is a member of the struct "Figure".
Can anyone please help me?

This is what I have so far.

#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;


struct Point // Point Structure
{
float x;
float y;
};

struct Figure //Figure Structure
{
char shape;
Point * vertices;
char * label;
};


int main()
{
char LINE[300];
int numOfFigures;
char SHAPE;
char * LABEL = new char[50];

FILE * pFile;
pFile = fopen ("a3q2tmp.txt", "w+"); //opening file to store user input
if (pFile != NULL)
{
printf("How many figures: "); //determining how many Figures to work with
scanf("%i%*c", &numOfFigures);

Figure * FigPtr = new Figure [numOfFigures];


for (int i = 1; i < numOfFigures + 1; i++)
{
printf("Figure %i: ", i);
fgets (LINE, 300, stdin);
fputs (LINE, pFile);
rewind (pFile);

fscanf(pFile, "%c", &SHAPE);
FigPtr[i].shape = SHAPE;
//printf("%c", FigPtr[i].shape);
fscanf(pFile, "%s", LABEL);
FigPtr[i].label = LABEL;
//printf("%s", FigPtr[i].label);
if (FigPtr[i].shape == "T")
{
//This is where i need to create an array of pointers
//to the data type struct Point. And this array has to be
//stored in the member vertices of struct Figure
}

}


delete [] FigPtr;
}

delete[] LABEL;

fclose (pFile);

return EXIT_SUCCESS;
}
FigPtr[i]->vertices = new Point(10)
What syntax do I have to use to delete this after so i dont get a memory leak?
:-( Use the power of C++ so you don't have to care about it.

Plus, you are missing a data member in Figure to hold the number of vertices in the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Figure
{
    char shape;
    Point *vertices;
    unsigned int t_vertices; //The total of vertices in the array.  You are missing this information.
    char *label;

    //This is C++ in all of its glory.
    Figure() : shape('\0'), vertices(0), t_vertices(0), label(0)
    { }
    //This is the destructor.  Will delete the array of vertices, if present.
    ~Figure()
    {
        if (vertices) delete[] vertices;
    }
}


Very simple, and will relieve you from thinking "Am I leaking memory?". No more memory leaks. Whenever you destroy a Figure (or one goes out of scope), you'll also destroy the associated vertices array. And that is C++. :-)
Last edited on
Thanks but im not to familiar with the use of constructors or destructors for that matter.
Then the C way of doing it would be to loop through the array of figures and call delete[] FigPtr(i).vertices; before destroying the said array of figures. Hardly impressive, prone to errors, and on more complex projects, just a pain to maintain.
so should i use constructers and destructers for the other struct Point?
The Point struct doesn't leak memory because its members are not dynamically allocated. In other words, you do not need to provide clean up for an instance of the Point struct, and therefore you don't need to write a constructor or destructor for them for this particular purpose.

By the way, the default constructor and destructor I wrote are the start. The absolute minimum should also cover the copy constructor and the assignment operator.
When i try this

FigPtr[i]->vertices = new Point[3]

I get the error base operand of '->' has non-pointer type 'Figure'
It should be FigPtr[i].vertices. The -> applies to pointers only. Your array is an array of Figures, not an array of pointers to Figures. Use the period.
should I use
FigPtr[i].vertices = new Point[3]
instead?
I bet you it took more time to ask that question and wait for the answer than it would have taken to test it out. :-S

Yes, use the period. Sigh...
yeah sorry right after i asked i tried it and it work.. That was stupid of me..
+1 to what webJose is preaching, although you still have to worry about memory problems with his setup.

If you want to get a solid handle on memory allocation and be SURE that you're not leaking or corrupting memory, you have to encapsulate.

The idea is simple. If Figure contains dynamically allocated memory... then Figure should be responsible for allocating AND freeing the memory. What's more, Figure should be impossible to misuse and produce a memory leak. IE: you want to make it idiotproof so that you don't shoot yourself in the foot later. This is why you would make some members private -- so that you can't mess with them in a way which would cause leaks/crashes/etc.


There are a dozen ways the above Figure class could leak memory, delete the wrong thing, or delete the same buffer twice. Therefore it's not an ideal solution.


Of course... the easy solution here is to just use STL container classes:

1
2
3
4
5
6
struct Figure
{
    char shape;
    std::vector<Point> vertices;
    string label;
};


The above is as close to idiot proof as you can make it without adding bounds checking.
I am running into another problem with my program. It is with the following portion of the code.

Figure * FigPtr = new Figure [numOfFigures];


for (int i = 0; i < numOfFigures; i++)
{
printf("Figure %i: ", i + 1);
fgets (LINE, 300, stdin);
fputs (LINE, pFile);
rewind (pFile);

fscanf(pFile, "%c", &SHAPE);
FigPtr[i].shape = SHAPE;

fscanf(pFile, "%s", LABEL);
FigPtr[i].label = LABEL;

if (FigPtr[i].shape == 'T')
{
FigPtr[i].vertices = new Point[3];
for (int j = 0; j < 3; j++)
{
fscanf(pFile, "%f", &xVert); //There is a problem here
FigPtr[i].vertices[j].x = xVert;
fscanf(pFile, "%f", &yVert); //There is a problem here
FigPtr[i].vertices[j].y = yVert;
printf("%f\n", FigPtr[i].vertices[j].x);
printf("%f\n", FigPtr[i].vertices[j].y);
}
}

}
With the 2 line above that i marked there is an issue. when my file contains the floating point numbers separated by spaces it works
fine but when the numbers are separated by commas it give me weird numbers, not the numbers i expected.

example: when reading in 0.0 0.1 0.2 0.3 0.4 0.5 it works as expected
but when reading in 0.0,0.1 0.2,0.3 0.4,0.5 it reads the first float correctly then I get really large numbers instead of the ones I expect
Wow, are you using your grandpa's programming books ? You are doing everything with old C. You need to ++ yourself there. :-)

Before you go any further and damage yourself, download and read this: http://msdn.microsoft.com/en-us/beginner/cc305129.aspx.

Pretty decent introduction to C++.

After that, get into STL. To be honest, I am not much of an STL guy, and that hurts me more often than not. Still, you should read about STL streams and do your file IO with them. They are easier to work with.

P. S.: When posting code, please use the CODE tags.
Last edited on
I know this looks like C but the course requires i program like this, using <cstdlib> and <cstdio> that is why i have been coding like
that. For what ever reason when I use fscanf, if the numbers are only seperated by a comma it doest read the float at store it in xVert or yVert. Why is that?
I just inserted anther fscanf to eat the comma so I think I figured it out.. Thanks to everyone for the help so far
Well, the comma is the thousands separator. This may be interfering with the read operation. Are you required to have that file format? I would have created a binary file and just read entire structs at a time. Well, that's a simplification. I would have created a binary file with a header telling me the offset and amount of Figure structs in the file, and telling me the offset of the vertices in the file. I would have then looped through the file creating the Figures, and then loading the vertices. But that's just me. :-)

Going back to your problem, can't you just use the text file with spaces? Like I said, I don't use fscanf(), and haven't used it for soooo long. I am not of big help there. And for that matter, I haven't read files with STL streams for almost the same time. I am a Windows guy and always use the Windows API.

Good luck with this one.

EDIT: Oops. Just saw you're good now.
Last edited on
yeah if its a thousands seperator i can see how that would cause me some problems but it seems to work now thanks again.
Topic archived. No new replies allowed.