2

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;
}
2
  • 1
    Think about it: where do you allocate enemies[0] (since it is a pointer)? Commented Aug 17, 2010 at 14:49
  • I took the liberty to add the #includes to your code, so it will compile. Commented Aug 17, 2010 at 14:54

6 Answers 6

4

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;
}
Sign up to request clarification or add additional context in comments.

Comments

3

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 ..

Comments

2

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;
}

Comments

2

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.

Comments

1

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.

1 Comment

Thanks, this is exactly what I was trying to do.
0

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 :-).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.