分配复合结构时,C程序崩溃

时间:2011-12-31 20:58:39

标签: c struct

操作系统: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 个答案:

答案 0 :(得分:5)

根据MAP_NAME_LENMAP_HMAP_WWORLD_HWORLD_W的值,您可能已在堆栈上创建了MASSIVE结构。不要那样做。堆栈相对较小,通常无法处理超过几兆字节的分配(并且通常一次只能处理几十千字节的分配)。鉴于您的常数值,您可能会遇到这些限制 - 您的World结构大约接近4MB,太大而无法合理地放入堆栈。

所以,相反,使用malloc在堆上分配它,或者作为全局或文件本地静态变量分配它:

World world;

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

int main()
{
    World *world = malloc(sizeof(*world));
    /* ... */
    free(world);
}

答案 1 :(得分:2)

我最好的猜测是你的World对象超过了最大堆栈大小。这取决于您如何定义MAP_NAME_LENMAP_HMAP_WWORLD_HWORLD_W

World结构的总大小至少为:WORLD_H * WORLD_W * (MAP_H * MAP_W * 2 * sizeof(Tile) + MAP_NAME_LEN)(加上编译器可能插入的任何填充)。

修改

现在您已经添加了常量,您可以计算出您的数据结构将消耗大约3.5MB(如果sizeof(Tile) == 4)。这对于堆栈来说太多了。默认堆栈大小通常约为1MB。使用malloc在堆上分配数据结构。

答案 2 :(得分:1)

当你typedef结构时,你必须给出一个名字,语法为typedef struct foo { /* ... */ } Foo;(foo标签是可选的)。

编辑现在,根据大小,很可能是堆栈溢出。 Map只使用4KB,因此World接近4MB。据我所知,Windows只给你一个较小的堆栈(假设它是1MB?)。

答案 3 :(得分:1)

default stack size(无论如何都是VS2010)是1MB。

sizeof(World) == 3921920,比1MB大3倍以上。

您看到的崩溃是堆栈溢出。

您可以尝试增加堆栈的大小(请参阅有关如何执行此操作的链接)或在堆上分配World对象。