LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Array of pointer to a structure (https://www.linuxquestions.org/questions/programming-9/array-of-pointer-to-a-structure-901634/)

instinct46 09-07-2011 01:19 PM

Array of pointer to a structure
 
I have the following wrote quite a few times and I'm getting the same error for all the lines its on, its properly going to be a silly mistake. So thank you for trying to help.

LINE
Code:

if(objContain[0].type == 1)
ERROR
Code:

EXPECTED PRIMARY EXPRESSION BEFORE '[' TOKEN
here is the structure and how I've initialized it.

Code:

struct objContain{
    unsigned int faces;
    int type; //TRIANGLE = 0 OR SQUARE = 1
    float **xcods;
    float **ycods;
    float **zcods;
};

Code:

struct objContain *objects;

objects = (struct objContain*) malloc(sizeof(struct objContain) * totalObjects);


johnsfine 09-07-2011 01:59 PM

Quote:

Originally Posted by instinct46 (Post 4464080)
Code:

if(objContain[0].type == 1)

I think you meant
Code:

if(objects[0].type == 1)
Quote:

Originally Posted by instinct46 (Post 4464080)
here is the structure and how I've initialized it.

Code:

struct objContain{ ...

So objContain is the structure name (the name for that kind of structure, not the name of any specific instance of the structure.)

Quote:

Code:

objects = (struct objContain*) malloc ...

objects is the pointer to the space you've allocated.

instinct46 09-07-2011 02:05 PM

Cheers, second simple mistake I've done today =/ well its bed time now, so I try again tomorrow lol.

rigor 09-07-2011 04:26 PM

Hi instinct46,

What are you actually trying to accomplish?

Although the subject of your post is "Array of pointer to a structure", instead, strictly speaking, you've seemingly declared a pointer to a single structure, and are trying to use it like a single pointer to an array of structures. Some compilers, especially older compilers, would potentially let you get away with that to an extent, if that's what
you really want. Some newer compilers with better error checking will complain.

cdecl is a handy utility of which various implementations are available on the web. You can use it to double check C declaration syntax. Here's the output of cdecl for three different declaration forms:

Quote:

struct objContain (*objects)[10];
declare objects as pointer to array[10] of struct objContain;

struct objContain *objects[10];
declare objects as array[10] of pointer to struct objContain;

struct objContain *objects;
declare objects as pointer to struct objContain;
If an array of pointers to structures is what you really want, an array of pointers, where each pointer points to a different instance of a objContain structure, then here is some test code that shows how that can be done.

Code:

# include <stdlib.h>
# include <stdio.h>


# define TRIANGLE        0
# define SQUARE                1

# define TOTAL_OBJECTS        10


struct objContain
{
    unsigned int        faces ;
    int                type ;                //TRIANGLE = 0 OR SQUARE = 1
    float              **xcods ;
    float              **ycods ;
    float              **zcods ;
} ;



int main(  int argc ,  char *argv[]  )
{
    struct objContain    *objects[  TOTAL_OBJECTS  ] ;
    int                  element_num ;


    // In case the implementation of C internals changes over time,
    // do nothing here that creates a dependency between the position in
    // memory of one structure and another.  Let the C implementation determine
    // the positions in memory.  So allocate each structure individually.
       
    for (  element_num = 0 ;  element_num < TOTAL_OBJECTS ;  element_num++  )
    {
        objects[ element_num ] =  ( struct objContain * ) malloc(  sizeof( struct objContain )  ) ;
               
        // Just to have type values for this test, let's put something in the type field
        // that isn't the same value all the time.
               
        objects[ element_num ]->type = ( element_num % 2 ) ;
    }


    for (  element_num = 0 ;  element_num < TOTAL_OBJECTS ;  element_num++  )
        printf(  "Shape # %d would be a %s\n" ,  element_num , (  objects[ element_num ]->type == SQUARE  )  ?  "SQUARE"  :  "TRIANGLE"  )  ;

}

For me that code compiles without any problems, and produces this output when it is run:

Quote:

Shape # 0 would be a TRIANGLE
Shape # 1 would be a SQUARE
Shape # 2 would be a TRIANGLE
Shape # 3 would be a SQUARE
Shape # 4 would be a TRIANGLE
Shape # 5 would be a SQUARE
Shape # 6 would be a TRIANGLE
Shape # 7 would be a SQUARE
Shape # 8 would be a TRIANGLE
Shape # 9 would be a SQUARE
Hope this helps.

johnsfine 09-07-2011 05:26 PM

Quote:

Originally Posted by kakaka (Post 4464262)
Although the subject of your post is "Array of pointer to a structure", instead, strictly speaking, you've seemingly declared a pointer to a single structure, and are trying to use it like a single pointer to an array of structures.

That is how pointers are typically and correctly used in C.

Quote:

Some newer compilers with better error checking will complain.
I don't think so.

Quote:

If an array of pointers to structures is what you really want, an array of pointers
You added s's to a phrase that doesn't make much sense without those s's. But either way the phrase doesn't fit the code very well. "pointer to array of a structure" would fit a lot better.

I chose to guess instinct46 wrote roughly the intended code and just titled the question poorly. English is a lot less precise than C.

rigor 09-07-2011 08:58 PM

The purpose of this thread is to help "instinct46" with a problem. Debating about other issues, seems rather off topic.

To that end I hope that the guess made by "johnsfine" as to what "instinct46" meant, was accurate, even though the guesses "johnsfine" made about what I meant, were incorrect.

If it's appropriate at all for LQ, and desirable, we can start threads, perhaps in other forums, about:

1) What do people think is typical in C, and is what's typically done in C, really Professional, or
has what's typically done in C, been what's given C a reputation for being more error prone that C++ or Java?

2) In what situations have you seen modern C development environments, complain, at build time or run time, errors or warnings, when you try to use pointers to arrays, for example with pointer arithmetic for multi-dimensional arrays, if
you haven't specified the dimensions of the array?

3) Can anyone agree on special considerations for using English grammar to describe C data structures?

ta0kira 09-07-2011 10:06 PM

Quote:

Originally Posted by kakaka (Post 4464472)
The purpose of this thread is to help "instinct46" with a problem. Debating about other issues, seems rather off topic.

Discussing the correctness and usefulness of other replies is usually considered on-topic.
Kevin Barry

instinct46 09-08-2011 12:10 PM

Well thank you for all off your replies. I'm a kinda new programmer, by new programmer I mean I've programmed since I was 12 but I've taught myself... so as you may of guessed errors and problems appear in my code.

I love the fact that I'm getting different programming, showing different aspects about my code which are correct/incorrect. I like this group, because its not usual that I can get help with twodimensional pointers to pointers of structures... very rare, my dad taught me.

If you want to read the program I will post it below. All I'm trying to do is learn OpenGL, and make a very basic engine to load such games, as pong. You must understand this code is not finished, and by not finished I MEAN really far from finish, but comments are welcome greatly.

////////////////////MAIN FILE///////////////////
Code:

#include <stdio.h>
#include <stdlib.h>

#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "objectheader.h"
#include "defaultobjects.c"


void defobj(struct objContain*);


int totalObjects = 1;
float moveZ = 0;
float moveY = 0;
float moveX = 0;
struct objContain *objects;

void handleKeypress(unsigned char key, int x, int y)
{
    ///////////////////////////////////////////////////
    //NEEDS TO LOOP THROUGH PLAYER CONTROLS STRUCTURE//
    ///////////////////////////////////////////////////
    switch(key){
        case 27:
            exit(0);
            break;
        //CONTROLS THE CAMERA
        case 45:
            moveZ += -0.5f;
            glutPostRedisplay();
            break;
        case 61:
            moveZ += 0.5f;
            glutPostRedisplay();
            break;
    }
}

//HANDLES KEYS LIKE UP + DOWN ARROWS, THIS CONTROLS THE CAMERA
void handleSpecialKey(int key, int x, int y)
{

    if(key == GLUT_KEY_LEFT){
        moveY += -0.1f;
        glutPostRedisplay();
    }

    if(key == GLUT_KEY_RIGHT){
        moveY += 0.1f;
        glutPostRedisplay();
    }

    if(key == GLUT_KEY_DOWN){
        moveX += -0.1f;
        glutPostRedisplay();
    }

    if(key == GLUT_KEY_UP){
        moveX += 0.1f;
        glutPostRedisplay();
    }
}


void initRendering()
{
    glEnable(GL_DEPTH_TEST);
}


void handleResize(int w, int h)
{
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(25, (double)w / (double)h, 1.0, 200.0);
}


void drawScene()
{
int loopa = 0;
int loopb = 0;

    //Clear information from last draw
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW); //Switch to the drawing mode
    glLoadIdentity(); //Reset the drawing perspective

    glTranslatef(moveY, moveX, moveZ);

    for(loopa = 0; loopa < totalObjects; loopa++){

        if(objects[0].type == 1) //IF OBJECT IS A SQUARE
            for(loopb = 0; loopb < objects[loopa].faces; loopa++){
                glBegin(GL_QUADS);
                    glVertex3f(objects[0].xcods[loopb][0],
                              objects[0].ycods[loopb][0],
                              objects[0].zcods[loopb][0]);
                    glVertex3f(objects[0].xcods[loopb][1],
                              objects[0].ycods[loopb][1],
                              objects[0].zcods[loopb][1]);
                    glVertex3f(objects[0].xcods[loopb][2],
                              objects[0].ycods[loopb][2],
                              objects[0].zcods[loopb][2]);
                    glVertex3f(objects[0].xcods[loopb][3],
                              objects[0].ycods[loopb][3],
                              objects[0].zcods[loopb][3]);
                glEnd();
            }

        if(objects[0].type == 1) //IF OBJECT IS A TRIANGLE
            for(loopb = 0; loopb < objects[loopa].faces; loopa++){
                glBegin(GL_TRIANGLES);
                    glVertex3f(objects[0].xcods[loopb][0],
                              objects[0].ycods[loopb][0],
                              objects[0].zcods[loopb][0]);
                    glVertex3f(objects[0].xcods[loopb][1],
                              objects[0].ycods[loopb][1],
                              objects[0].zcods[loopb][1]);
                    glVertex3f(objects[0].xcods[loopb][2],
                              objects[0].ycods[loopb][2],
                              objects[0].zcods[loopb][2]);
                glEnd();
            }
    }

    glutSwapBuffers();
}


int main(int argc, char *argv[])
{
    //INITILIZE OPENGL
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(700, 700);

    //CREATE THE WINDOW
    glutCreateWindow("v0.4 Basic OpenGL Coding");
    initRendering();

    objects = (struct objContain*) malloc(sizeof(struct objContain) * totalObjects);
    defobj(objects);

    glutDisplayFunc(drawScene);
    glutKeyboardFunc(handleKeypress);
    glutSpecialFunc(handleSpecialKey);
    glutReshapeFunc(handleResize);

    //THIS HAS BEEN SET, SO THAT ALL KEYPRESSES CAN BE MORE EFFECTIVELY IMPLAMENTED
    glutIgnoreKeyRepeat(true);

    glutMainLoop();

return 0;
}


OBJECT HEADER
Code:

#ifndef _OBJECT_HEADER_H_
#define _OBJECT_HEADER_H_

#include <stdio.h>

struct objContain{
    unsigned int faces;
    int type; //TRIANGLE = 0 OR SQUARE = 1
    float **xcods;
    float **ycods;
    float **zcods;
};

#endif


Code:

#ifndef _CONTROLS_HEADER_H_
#define _CONTROLS_HEADER_H_

//CONTROLS ARE BASIC FOR MOST STANDARD GAMES
struct controls{
    short int up;
    short int down;
    short int left;
    short int right;

    short int fire;
    short int firealt;
    short int jump;
};

#endif


DEFAULT OBJECTS - MADE FOR TESTING
Code:

#include <stdio.h>
#include <stdlib.h>

#include "objectheader.h"


void defobj(struct objContain *tmpstruc){
int loopa = 0;

    ///////////////////////////////////////
    //NEEDS TO READ IN FROM A BINARY FILE//
    ///////////////////////////////////////

    tmpstruc[0].faces = 1;
    tmpstruc[0].type = 1;

    tmpstruc[0].xcods = (float**) malloc(sizeof(int) * (tmpstruc[0].faces));
    for(loopa = 0; loopa < tmpstruc[0].faces; loopa++)
        tmpstruc[0].xcods[loopa] = (float*) malloc(sizeof(float) * (tmpstruc[0].type + 3));

    tmpstruc[0].ycods = (float**) malloc(sizeof(float) * (tmpstruc[0].faces));
    for(loopa = 0; loopa < tmpstruc[0].faces; loopa++)
        tmpstruc[0].ycods[loopa] = (float*) malloc(sizeof(float) * (tmpstruc[0].type + 3));

    tmpstruc[0].zcods = (float**) malloc(sizeof(float) * (tmpstruc[0].faces));
    for(loopa = 0; loopa < tmpstruc[0].faces; loopa++)
        tmpstruc[0].zcods[loopa] = (float*) malloc(sizeof(float) * (tmpstruc[0].type + 3));

        tmpstruc[0].xcods[0][0] = -0.5f;
        tmpstruc[0].xcods[0][1] = 0.5f;
        tmpstruc[0].xcods[0][2] = 0.5f;
        tmpstruc[0].xcods[0][3] = -0.5f;

        tmpstruc[0].ycods[0][0] = -0.5f;
        tmpstruc[0].ycods[0][1] = -0.5f;
        tmpstruc[0].ycods[0][2] = 0.5f;
        tmpstruc[0].ycods[0][3] = 0.5f;

        tmpstruc[0].zcods[0][0] = -2.0f;
        tmpstruc[0].zcods[0][1] = -2.0f;
        tmpstruc[0].zcods[0][2] = -2.0f;
        tmpstruc[0].zcods[0][3] = -2.0f;
}


instinct46 09-08-2011 12:35 PM

Quote:

Originally Posted by kakaka (Post 4464472)
The purpose of this thread is to help "instinct46" with a problem. Debating about other issues, seems rather off topic.

To that end I hope that the guess made by "johnsfine" as to what "instinct46" meant, was accurate, even though the guesses "johnsfine" made about what I meant, were incorrect.

If it's appropriate at all for LQ, and desirable, we can start threads, perhaps in other forums, about:

1) What do people think is typical in C, and is what's typically done in C, really Professional, or
has what's typically done in C, been what's given C a reputation for being more error prone that C++ or Java?

2) In what situations have you seen modern C development environments, complain, at build time or run time, errors or warnings, when you try to use pointers to arrays, for example with pointer arithmetic for multi-dimensional arrays, if
you haven't specified the dimensions of the array?

3) Can anyone agree on special considerations for using English grammar to describe C data structures?


I welcome all answers, even those that aren't relate to the question, as long as they are relative to the coding. It is nice to know that people, are willing to give their ideas and "understanding standards" to my code. Sorry everyone about my grammer, I am english and I should know better. (I'm not an english teacher. My dad kinda is, so no doubht he will treat me like a child for a while after seeing this lol.)

**EDIT** I had woke up seconds before this, and didn't have minutes to recheck it.

johnsfine 09-08-2011 01:14 PM

Quote:

Originally Posted by instinct46 (Post 4466548)
Sorry everyone about my grammer, I am english and I should know better. (I'm not an english teacher. My dad kinda is, so no doubht he will treat me like a child for a while after seeing this lol._

Maybe it would be best if your father would read this thread and give you appropriate feedback.

I expect a lot of poor English in this forum because English is a second language for many people posting here. No matter how poor their English is, I am acutely aware that it is better than my second language abilities. So I avoid criticizing.

But very bad grammar from someone whose first language is English conveys either laziness or direct disrespect (laziness in the way you ask technical questions also implies a certain disrespect).

I'm only commenting on it because you called attention to it yourself. I generally prefer ignore disrespect and/or other flaws in the posts and focus on the technical aspects. (Obviously I'm not 100% successful at that).

instinct46 09-08-2011 01:34 PM

Quote:

Originally Posted by johnsfine (Post 4466573)
Maybe it would be best if your father would read this thread and give you appropriate feedback.

I expect a lot of poor English in this forum because English is a second language for many people posting here. No matter how poor their English is, I am acutely aware that it is better than my second language abilities. So I avoid criticizing.

But very bad grammar from someone whose first language is English conveys either laziness or direct disrespect (laziness in the way you ask technical questions also implies a certain disrespect).

I'm only commenting on it because you called attention to it yourself. I generally prefer ignore disrespect and/or other flaws in the posts and focus on the technical aspects. (Obviously I'm not 100% successful at that).

I'm sorry, about my English. I'm from England, If you where from here, you would notice that every town, speaks differently. I do ask my dad. I came here for professional help. I pointed out that I was sorry about my English, because I didn't see how it was relevant.

The title is wrong, because I didn't know where I was going wrong, otherwise I wouldn't of asked for help. Also bringing up my English, because I brought it up, isn't important. I've seen many people, point out that their English, isn't the best.Yet I've never seen someone, in my time insult someone as you just have.

And, how about you give me a break. Your grammar is naff in its self! I came here for coding help not English lessons.

I've been at work for 16h shifts, and haven't had a day off in 9days.. and will not have a day off in another 16days! I program, because it is a hobby. I've even had to correct myself a few times, because I'm tired.

Also last thing, but my english shouldn't be under-attack! my coding should.

johnsfine 09-08-2011 02:17 PM

Quote:

Originally Posted by instinct46 (Post 4466585)
And, how about you give me a break. Your grammar is naff in its self! I came here for coding help not English lessons.

Sorry I offended you. I meant all my comments to be constructive. Parts of your post that motivated my reply are no longer there. I specifically avoided quoting what motivated my reply because I thought doing so would be more insulting and less constructive. Anyway, I'll stop talking about grammar now and wait for the discussion to go back to code.


All times are GMT -5. The time now is 07:56 PM.