Сбой программы на С при выделении составной структуры - PullRequest
0 голосов
/ 01 января 2012

ОС: Windows 7, компилятор: GCC 3.2.3 (MinGW)

Я создал эти три структуры данных в C:

#define MAP_NAME_LEN    30
#define MAP_W           25
#define MAP_H           19
#define WORLD_W         32
#define WORLD_H         32

typedef unsigned char byte;

typedef struct Tile
{
    byte type;
    byte character;
    byte fgColor;
    byte bgColor;
};

typedef struct Map
{
    char name[MAP_NAME_LEN];
    Tile overlay[MAP_H][MAP_W];
    Tile underlay[MAP_H][MAP_W];
};

typedef struct World
{
    Map area[WORLD_H][WORLD_W];
};

Когда я пытаюсь создать отдельные экземпляры Tile и / или Map, все нормально, никаких проблем, все работает. Но тогда, если я попытаюсь создать Мир, как ...

int main()
{
    World world;
}

... программа просто падает (Windows 7 говорит, что программа потерпела крах, ищет решение и т. Д.). Ребята, вы понимаете, почему это происходит?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 01 января 2012

В зависимости от значений MAP_NAME_LEN, MAP_H, MAP_W, WORLD_H и WORLD_W, вы, возможно, создали структуру MASSIVE в стеке.Не делай этого.Стек является относительно небольшим и, как правило, не может обрабатывать выделения размером более нескольких мегабайт (и часто может обрабатывать только несколько десятков килобайт за раз).Учитывая ваши постоянные значения, вы, вероятно, столкнетесь с этими ограничениями - ваша структура World имеет размер почти 4 МБ, слишком большой, чтобы разумно помещать ее в стек.

Поэтому вместо этого распределите ее накуча с malloc, или как глобальная или локальная статическая переменная файла:

World world;

int main()
{
    /* ... */
}

или

int main()
{
    World *world = malloc(sizeof(*world));
    /* ... */
    free(world);
}
2 голосов
/ 01 января 2012

Мое лучшее предположение состоит в том, что ваш World объект превышает максимальный размер стека.Это зависит от того, как вы определили MAP_NAME_LEN, MAP_H, MAP_W и WORLD_H, WORLD_W.

. Общий размер структуры World не менее: WORLD_H * WORLD_W * (MAP_H * MAP_W * 2 * sizeof(Tile) + MAP_NAME_LEN) (плюслюбой заполнитель, который компилятор может вставить)*).Это слишком много для стека.Размер стека по умолчанию обычно составляет около 1 МБ.Используйте malloc для выделения структуры данных в куче.

1 голос
/ 01 января 2012

Размер стека по умолчанию (с VS2010 в любом случае) равен 1 МБ.

sizeof(World) == 3921920, что более чем в 3 раза превышает 1 МБ.

Сбой, который вы видите, является переполнением стека.

Вы можете попытаться увеличить размер стека (см. Ссылку, как это сделать) или выделить объект World в куче.

1 голос
/ 01 января 2012

Когда вы typedef структура, вам нужно дать имя, синтаксис typedef struct foo { /* ... */ } Foo; (тег foo не является обязательным).

Редактировать Теперь, с размерамиочень вероятно переполнение стека.Map использует только 4 КБ, поэтому World приближается к 4 МБ.Насколько я помню, Windows дает вам только меньший стек (мне кажется, это был 1 МБ?).

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