dynamic memory allocation of an array of pointers to structures

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bimbam
    New Member
    • Aug 2007
    • 19

    dynamic memory allocation of an array of pointers to structures

    Hi,

    I've been trying to allocate dynamicaly an array of pointers to structures. As it didn't work, I tried to reduce the problem as much as possible. This is what I have :

    [code=c]
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct
    {
    int x;
    int y;
    }struct_p;


    int main()
    {
    int i,n=2;
    struct_p *p;
    p=calloc(n,size of(struct_p*));
    for (i=0;i<n;i++)
    {
    p[i]->x=0;
    p[i]->y=1;
    }
    }

    [/code]

    When compiling it with gcc, I get the errors:


    new.c:18: error: invalid type argument of ‘->’
    new.c:19: error: invalid type argument of ‘->’


    I thought that by using calloc the way I did it, I had defined an array of pointers to structures. So the use of 'p[i]->x' for example, should give the content of the strucure field 'x' in the structure of adress 'p[i]'. Where am I wrong? What should I do?

    Regards
  • sanctus
    New Member
    • Mar 2007
    • 84

    #2
    Originally posted by bimbam
    Hi,

    I've been trying to allocate dynamicaly an array of pointers to structures. As it didn't work, I tried to reduce the problem as much as possible. This is what I have :

    [code=c]
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct
    {
    int x;
    int y;
    }struct_p;


    int main()
    {
    int i,n=2;
    struct_p *p;
    p=calloc(n,size of(struct_p*));
    for (i=0;i<n;i++)
    {
    p[i]->x=0;
    p[i]->y=1;
    }
    }

    [/code]

    When compiling it with gcc, I get the errors:


    new.c:18: error: invalid type argument of ‘->’
    new.c:19: error: invalid type argument of ‘->’


    I thought that by using calloc the way I did it, I had defined an array of pointers to structures. So the use of 'p[i]->x' for example, should give the content of the strucure field 'x' in the structure of adress 'p[i]'. Where am I wrong? What should I do?

    Regards
    p[i] is no more an adress...p[i] is an element of an array and not a pointer to an element so you can't use ->. How you use calloc you allocate memory for an array of 2 objects of size of struct_p, so that should be fine. I think it should work if you replace '->' by '.'
    Regards

    Comment

    • bimbam
      New Member
      • Aug 2007
      • 19

      #3
      Originally posted by sanctus
      p[i] is no more an adress...p[i] is an element of an array and not a pointer to an element so you can't use ->. How you use calloc you allocate memory for an array of 2 objects of size of struct_p, so that should be fine. I think it should work if you replace '->' by '.'
      Regards
      Thank you for your answer.

      I used sizeof(struct_p *) and not sizeof(struct_p ). Does'nt it make any difference? I thought that, this way, the elements of the array would be pointers.

      Regards

      Comment

      • sanctus
        New Member
        • Mar 2007
        • 84

        #4
        Originally posted by bimbam
        Thank you for your answer.

        I used sizeof(struct_p *) and not sizeof(struct_p ). Does'nt it make any difference? I thought that, this way, the elements of the array would be pointers.

        Regards
        Actually I don't know well the operator sizeof, but from what I understand sizeof doesn't define any type (i.e. pointer or variable) just giving the size in octets. Considering this you should use sizeof(struct_p ), because you want allocate memory to p so that it can hold two objects of type struct_p.
        Using sizeof(struct_p *) it means that p can hold 2 objects of size of a pointer to struct_p.
        I'm not sure about this, but I think it is this way.

        Did you still get errors using the '.' instead of the '->' ?

        Comment

        • bimbam
          New Member
          • Aug 2007
          • 19

          #5
          Originally posted by sanctus
          Actually I don't know well the operator sizeof, but from what I understand sizeof doesn't define any type (i.e. pointer or variable) just giving the size in octets. Considering this you should use sizeof(struct_p ), because you want allocate memory to p so that it can hold two objects of type struct_p.
          Using sizeof(struct_p *) it means that p can hold 2 objects of size of a pointer to struct_p.
          I'm not sure about this, but I think it is this way.

          Did you still get errors using the '.' instead of the '->' ?

          It works with 'sizeof(struct_ p)' (and '.'). You were right. Thank you for your help.

          Regards

          Comment

          • bimbam
            New Member
            • Aug 2007
            • 19

            #6
            Originally posted by sanctus
            Actually I don't know well the operator sizeof, but from what I understand sizeof doesn't define any type (i.e. pointer or variable) just giving the size in octets. Considering this you should use sizeof(struct_p ), because you want allocate memory to p so that it can hold two objects of type struct_p.
            Using sizeof(struct_p *) it means that p can hold 2 objects of size of a pointer to struct_p.
            I'm not sure about this, but I think it is this way.

            Did you still get errors using the '.' instead of the '->' ?

            But in that case, how would you allocate dynamically the memory of an array of pointers if not with 'p=calloc(n,siz eof(struct_p*)) '?

            Regards

            Comment

            • JosAH
              Recognized Expert MVP
              • Mar 2007
              • 11453

              #7
              Originally posted by bimbam
              But in that case, how would you allocate dynamically the memory of an array of pointers if not with 'p=calloc(n,siz eof(struct_p*)) '?

              Regards
              If you want to allocate n of those pointers, the way you described it is the way
              to do it; but when you want to assign whatever calloc returned you need a
              struct_p** (note the double star) because it points to zero or more of those
              struct_p*s (not the single star).

              If you do it like this you have an array of struct pointers but none of the pointers
              point to such a struct yet, i.e. you have to initialize the array elements (the pointers)
              if you want to dereference anything from them.

              kind regards,

              Jos

              Comment

              • bimbam
                New Member
                • Aug 2007
                • 19

                #8
                Originally posted by JosAH
                If you want to allocate n of those pointers, the way you described it is the way
                to do it; but when you want to assign whatever calloc returned you need a
                struct_p** (note the double star) because it points to zero or more of those
                struct_p*s (not the single star).

                If you do it like this you have an array of struct pointers but none of the pointers
                point to such a struct yet, i.e. you have to initialize the array elements (the pointers)
                if you want to dereference anything from them.

                kind regards,

                Jos
                Thanks a lot for your answer.

                Everything seems to work. I just want to be sure that I did the memory allocation properly so that nothing will be overwriten later and no memory was wasted.

                Could you quickly have a look at these few lines to see if everything is "perfect"? Do you have suggestions to improve it?

                [code=c]
                #include <stdio.h>
                #include <stdlib.h>

                typedef struct
                {
                int x;
                int *y;
                }struct_p;


                int main()
                {
                int i,j,n=3;
                int x,y;
                struct_p **p;
                p=malloc(n*size of(struct_p*));

                for (i=0;i<n;i++)
                {
                p[i]=malloc(sizeof( struct_p));
                p[i]->x=0;
                p[i]->y=malloc(n*siz eof(int));
                }

                for (i=0;i<n;i++)
                {
                printf("p[%d]->x=%d | ",i,p[i]->x);
                for (j=0;j<n;j++)
                printf("p[%d]->y[%d]=%d ",i,j,p[i]->y[j]);
                printf("\n");
                }
                }

                [/code]

                The output is as expected:

                p[0]->x=0 | p[0]->y[0]=0 p[0]->y[1]=0 p[0]->y[2]=0
                p[1]->x=0 | p[1]->y[0]=0 p[1]->y[1]=0 p[1]->y[2]=0
                p[2]->x=0 | p[2]->y[0]=0 p[2]->y[1]=0 p[2]->y[2]=0


                Regards

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Yep, that's all correct as far as I can see now.

                  kind regards,

                  Jos

                  edit: you could've done 'calloc(n, sizeof(struct_p *))' instead of malloc(n*sizeof (struct_p*))'
                  but it doesn't matter.

                  Comment

                  • bimbam
                    New Member
                    • Aug 2007
                    • 19

                    #10
                    Originally posted by JosAH
                    Yep, that's all correct as far as I can see now.

                    kind regards,

                    Jos

                    edit: you could've done 'calloc(n, sizeof(struct_p *))' instead of malloc(n*sizeof (struct_p*))'
                    but it doesn't matter.

                    Thanks.

                    To 'desallocate', is 'free(p)' enough? Or do I have to do everything in reverse to free each field of all the structures, free the structures abd then free the array?
                    Regards

                    Comment

                    • JosAH
                      Recognized Expert MVP
                      • Mar 2007
                      • 11453

                      #11
                      Originally posted by bimbam
                      Thanks.

                      To 'desallocate', is 'free(p)' enough? Or do I have to do everything in reverse to free each field of all the structures, free the structures abd then free the array?
                      Regards
                      Yep, you have to do it all yourself. C's free() function is quite stupid: it frees
                      the memory directly pointed to by its parameter and that's about it. It doesn't
                      know that that memory contains pointers to other 'things' that should be free'd
                      as well. You need C++ if you want that type of functionality. Or you can build
                      a nice little function for exactly this purpose.

                      kind regards,

                      Jos

                      Comment

                      Working...