Thread: Help with a C struct

1. 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. 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;
}```

3. 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. Originally Posted by Unee0x
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. Originally Posted by 0x47617279
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. Originally Posted by c99tutorial
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).

7. Originally Posted by grumpy
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. Originally Posted by c99tutorial
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.