Массив указателей на структуру, только SIGSEGVs при отладке - PullRequest
2 голосов
/ 17 августа 2010

Следующий код вызывает SIGSEGV, но только во время отладки.

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

Ответы [ 6 ]

4 голосов
/ 17 августа 2010

Вы создаете пространство только для 16 указателей на врага, но не создаете фактические вражеские объекты, которые вы пытаетесь использовать.

Вот пример, где я создаю вражеский объект для первого указателяв массиве.

#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;
}
3 голосов
/ 17 августа 2010

Вы выделили память для 16 enemy * указателей, но вы не выделили пространство для самих 16 enemy структур. Есть два способа это исправить. Одним из них является добавление цикла, который распределяет каждую из 16 enemy структур по очереди:

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

Другой - удалить один уровень косвенности. Если вы объявляете enemy *enemies, вы можете выделить 16 структур сразу и отказаться от цикла. Если нет необходимости в двойном косвенном обращении, это было бы моим предпочтительным решением:

int main()
{
    enemy *enemies;
    enemies = (enemy *) malloc(sizeof(enemy) * 16);

    enemies[0].type=23;

    printf("%i",enemies[0].type);
    return 0;
}

Обратите внимание, что оператор -> переключается на ..

2 голосов
/ 17 августа 2010

Ну, это должно произойти сразу же ... потому что вы инициализируете массив (массив указателей). И тогда вы ОБРАЩАЕТЕСЬ к первому предмету (враги [0]), который должен дать вам любой случайный указатель. Вы пытаетесь получить доступ к этой произвольной области памяти для записи в значение 23.

Это должно быть примерно так:

enemies = (enemy **)malloc(sizeof(enemy *) * 16);
for (int i = 0; i < 16; i++) {
  enemies[i] = (enemy *)malloc(sizof(enemy));
}

... прежде чем вы получите к нему доступ.

2 голосов
/ 17 августа 2010

Вам нужно создать структуру, на которую указывают указатели. Причина, по которой он дает только SEGV во время отладки, состоит в том, что во время отладки выполняется некоторая инициализация, чтобы вызвать подобные вещи в segfault; все случайные данные во врагах [0], когда вы не отлаживаете, разыменовываются и просто не вызывают segfault.

Ваш код, вероятно, хочет читать так:

    int main()
{
    enemy *enemies;
    enemies=(enemy *)malloc(sizeof(enemy)*16);

    enemies[0].type=23;

    printf("%i",enemies[0].type);
    return 0;
}
1 голос
/ 17 августа 2010

Похоже, вы хотите выделить массив указателей на структуру, но вы пытаетесь получить доступ к структуре без выделения места для них. Вы должны сделать:

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.
0 голосов
/ 17 августа 2010

В моей системе (x86, Debian GNU / Linux) код всегда имеет ошибки по умолчанию.

Обратный след сбоя:

signal SIGSEGV, Segmentation fault.
0x08048413 in main () at en.c:16
16      enemies[0]->type=23;
(gdb) 

Цитированное назначение (враги [0] -> тип =23;) это проблема.Вы выделяете память только для массива врагов, который представляет собой массив указателей.Затем вы получаете доступ к структуре, на которую должны указывать враги [0], но у вас нет выделенной памяти для структуры, а враги [0] - неинициализированный указатель, следовательно, segfault.

В подобных случаяхОтладчик - твой друг: -).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...