Reputation: 23
The following code causes a SIGSEGV, but only while debugging.
#include <stdio.h>
#include <stdlib.h>
typedef struct enemy_desc
{
int type;
int x;
int y;
}enemy;
int main()
{
enemy **enemies;
enemies=(enemy **)malloc(sizeof(enemy *)*16);
enemies[0]->type=23;
printf("%i",enemies[0]->type);
return 0;
}
Upvotes: 2
Views: 367
Reputation: 28257
You are only creating space for 16 pointers to enemy, but are not creating the actual enemy objects that you're attempting to use.
Here is an example where I create an enemy object to the first pointer in the array.
#include <iostream>
typedef struct enemy_desc
{
int type;
int x;
int y;
}enemy;
using namespace std;
int main(int argc, char **argv)
{
enemy **enemies;
enemies=(enemy **)malloc(sizeof(enemy *)*16);
memset(enemies, 0, sizeof(enemy*)*16);
enemies[0] = (enemy *) malloc(sizeof(enemy));
memset(enemies[0], 0, sizeof(enemy));
enemies[0]->type=23;
printf("type: %i x: %i y: %i\n\n",enemies[0]->type, enemies[0]->x, enemies[0]->y);
enemies[0]->x = 10;
enemies[0]->y = 25;
enemies[0]->type= 7;
printf("type: %i x: %i y: %i\n\n",enemies[0]->type, enemies[0]->x, enemies[0]->y);
free(enemies[0]);
free(enemies);
return 0;
}
Upvotes: 4
Reputation: 361849
You have allocated memory for 16 enemy *
pointers, but you have not allocated room for the 16 enemy
structs themselves. There are two ways to fix this. One is to add a loop that allocates each of the 16 enemy
structs one by one:
int main()
{
enemy **enemies;
int i;
enemies = (enemy **) malloc(sizeof(enemy *) * 16);
for (i = 0; i < 16; ++i) {
enemies[i] = (enemy *) malloc(sizeof(enemy));
}
enemies[0]->type = 23;
printf("%i",enemies[0]->type);
return 0;
}
The other is to remove one level of indirection. If you declare enemy *enemies
then you can allocate the 16 structs at once and forgo a loop. If there's no need for the double indirection this would be my preferred solution:
int main()
{
enemy *enemies;
enemies = (enemy *) malloc(sizeof(enemy) * 16);
enemies[0].type=23;
printf("%i",enemies[0].type);
return 0;
}
Notice that the ->
operator switches to .
.
Upvotes: 3
Reputation: 92384
Well it should crash right away... because you initialize the array of (array of pointers). And then you DEREFERENCE the first item (enemies[0]) which should give you any random pointer. You try to access that random memory area to write in the value 23.
It should be along the lines of this:
enemies = (enemy **)malloc(sizeof(enemy *) * 16);
for (int i = 0; i < 16; i++) {
enemies[i] = (enemy *)malloc(sizof(enemy));
}
... before you access it.
Upvotes: 2
Reputation: 455282
Looks like you want to allocate an array of pointer to struct, but you're trying to access the struct without allocating space for them. You should do:
enemy **enemies;
enemies=(enemy **)malloc(sizeof(enemy *)*16);
for(i=0;i<16;i++) // allocate space for the structs
enemies[i] = (enemy *)malloc(sizeof(enemy))
enemies[0]->type=23; // now access type field of the first struct obj in array.
Upvotes: 1
Reputation: 83628
On my system (x86, Debian GNU/Linux), the code always segfaults.
Crash backtrace:
signal SIGSEGV, Segmentation fault.
0x08048413 in main () at en.c:16
16 enemies[0]->type=23;
(gdb)
The assignment cited (enemies[0]->type=23;) is the problem. You only allocate memory for the array enemies, which is an array of pointers. You then access the structure that enemies[0] is supposed to point to, but you have not allocated memory for the structure, and enemies[0] is an uninitialized pointer, hence the segfault.
In cases like this, a debugger is your friend :-).
Upvotes: 0
Reputation: 764
You need to create the struct that the pointers point to. The reason why it only gives a SEGV while debugging will be that there's some initialisation done during debugging to cause this sort of thing to segfault; whatever random data's in enemies[0] when you're not debugging is getting dereferenced and is just happening not to cause a segfault.
Your code probably wants to read like this:
int main()
{
enemy *enemies;
enemies=(enemy *)malloc(sizeof(enemy)*16);
enemies[0].type=23;
printf("%i",enemies[0].type);
return 0;
}
Upvotes: 2