Thread: Help with a C struct

  1. #1
    Registered User Unee0x's Avatar
    Join Date
    Nov 2011
    Posts
    12

    Help with a C struct

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


    I am trying to copy 64 Points into an array called Sq and print out one point at Sq[2][5], and it compiles but at runtime I get a segmentation fault 11 error.

    Can anyone help understand why this error occurs, and some guidance on fixing it...?

    Code:
    struct Point
    {
      int x;
      int y;
    };
    int main() {
      struct Point *P;
      int Sq[P->x][P->y];
      for(P->x=1;P->x<=8;P->x++)
        for(P->y=1;P->y<=8;P->y++)
          //printf("(%d,%d)\n",P->x,P->y);                                          
          printf("%d\n",Sq[2][5]);
      return 0;
    }

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    P is an unitialised pointer, so even accessing its value causes undefined behaviour. Creating a pointer does not create a pointee, let alone make the pointer point at anything. This means that P does not point at anything that can be used in your program. Similarly, it is invalid to use P->x or P->y in any way.

    Try doing this;
    Code:
    struct Point
    {
      int x;
      int y;
    };
    int main() {
      struct Point p = {10,12};
      struct Point *P = &p;     /*   We make P point at an actual object */
      int Sq[P->x][P->y];      /*  P->x has a value of 10 and P->y has a value of 12 */
      for(P->x=1;P->x<=8;P->x++)
        for(P->y=1;P->y<=8;P->y++)
          //printf("(%d,%d)\n",P->x,P->y);                                         
          printf("%d\n",Sq[2][5]);
      return 0;
    }
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Jan 2013
    Location
    UK
    Posts
    19
    You can't create an array of varibles with a number which could change, it has to be a static number. You could create a int pointer and then malloc the amount of memory you required.



    Code:
    struct Point{
        int x;
        int y;
    };
    
    int main()
    { 
       struct Point *p; 
       int loopa; 
       int **Sq; 
       
        p = malloc(sizeof(struct Point)); 
       
        p->x = 10;
        p->y = 12;
        
        Sq = malloc(sizeof(*int) * p->x); 
           
        for(loopa = 0; loopa < p->x; loopa++)
            Sq[loopa] = malloc(sizeof(*int) * p->y);
        
        for(P->x=1; P->x<=8; P->x++) 
            for(P->y=1; P->y<=8; P->y++) 
                printf("%d\n",Sq[2][5]); 
     
    return 0;
    }

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Unee0x View Post
    I am trying to copy 64 Points into an array called Sq and print out one point at Sq[2][5], and it compiles but at runtime I get a segmentation fault 11 error.
    I personally have no clue what you want to achieve.

    What should be stored in "Sq"?
    What do the magic numbers "2" and "5" mean?
    What's the use of your "Point" structure?

    Bye, Andreas

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by 0x47617279 View Post
    You can't create an array of varibles with a number which could change, it has to be a static number.
    This is not correct. Creating an array of a size not known at compile time is known as a VLA (variable length array) and performs a stack allocation.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by c99tutorial View Post
    This is not correct. Creating an array of a size not known at compile time is known as a VLA (variable length array) and performs a stack allocation.
    Your correction is also inaccurate. While it is true that the size of a VLA is determined at run time, its size cannot subsequently change.

    I've lost track of the number of times folks have expected samples like these to work.
    Code:
    /*   Danger:  code with undefined behaviour here */
    int main()
    {
          int i, n;
          int x[n];
          n = some_value_obtained_at_runtime();
    
          for (i = 0; i < n; ++) x[i] = something();
    }
    or
    Code:
    /*   Danger:  code with undefined behaviour here */
    int main()
    {
          int i, n;
          n = some_value_obtained_at_runtime();
          int x[n];
    
          for (i = 0; i < n; ++) x[i] = something();    /* this is actually okay */
    
          n = some_larger_value_obtained_at_runtime();
          for (i = 0; i < n; ++) x[i] = something();    /* this is not, as the array has not resized */
    }
    Technically, C does not support a notion of stack either, but that's a philosophical point. Stack and heap and other things are implementation specifics. There is nothing stopping the compiler from implementing VLAs under the covers using dynamic memory allocation (malloc() when the array is created, free() to release it).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by grumpy View Post
    I've lost track of the number of times folks have expected samples like these to work.
    Ok, correction is noted.

    However, your example could be corrected as follows:

    Code:
    int main()
    {
          int i, n;
          n = some_value_obtained_at_runtime();
          {
                int x[n];
                for (i = 0; i < n; i++) x[i] = something();
                /* do something interesting with x */
          }
          n = some_larger_value_obtained_at_runtime();
          {
                int x[n];
                for (i = 0; i < n; i++) x[i] = something();
                /* do something interesting with x */
          }
    }
    I suppose by stack I mean the opening and closing braces supports the notion of a stack, even if they aren't actually implemented this way behind the scenes.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by c99tutorial View Post
    However, your example could be corrected as follows:
    My examples stand. I was describing things that people incorrectly expect to work. Your example is also not changing the size of anything. It is creating two distinct VLAs, each named x, in different scopes.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting array of struct inside struct
    By blueboyz in forum C Programming
    Replies: 13
    Last Post: 04-24-2012, 02:15 AM
  2. Using data struct and I got an error in struct function
    By abrofunky in forum C++ Programming
    Replies: 4
    Last Post: 02-18-2012, 07:47 PM
  3. Replies: 1
    Last Post: 05-12-2011, 01:02 AM
  4. struct holding data inside a linked list struct
    By icestorm in forum C Programming
    Replies: 2
    Last Post: 10-06-2009, 12:49 PM
  5. returning a pointer of a struct of a struct array...
    By myrddinb in forum C Programming
    Replies: 1
    Last Post: 04-13-2004, 06:49 PM