得到一个非常烦人的分段错误...在C中mallocing 2d数组

时间:2010-09-29 21:10:44

标签: c arrays graphics malloc multidimensional-array

我遇到这个问题。首先,这是我写的一个简单的图形库。

我正在做的是使用程序员选择的维度来声明多个“虚拟屏幕”。为此,我需要根据屏幕包含的像素数动态分配足够的内存。

分配这个内存的函数似乎只在我的程序中工作一次,然后每次调用它就失败(带有段错误)。我认为这个问题可能就是我在虚拟屏幕上传递的方式(screen_t)。我实现它的方式是,函数new_screen不返回指针,而是实际的屏幕本身。我想也许这是一个错误。此外,当一个函数(如set_current_screen)需要一个屏幕作为其参数之一时,它会传递地址,如下所示:

set_current_screen(&screen_variable);

这是正确的方法吗?当我拨打new_screen时,这是导致段错误的原因吗?

提前致谢。代码是一个头文件(非常不完整),一个c文件在一个屏幕上绘制一些rects,尝试创建另一个,获得段错误。他们在这里:

hgl.h

main.c

3 个答案:

答案 0 :(得分:3)

首先,在第二次new_screen()调用中,您的代码不是SEGFAULT。你误导了我们所有人:)当你试图访问它时代码崩溃。你的主要问题在于这一行:

 47     vscreen.bitmap[i] = malloc(height * sizeof(int));

由于您已经分配了一个指向struct pixel的数组的指针,为什么要获得int的大小。您应该将其更改为以下内容:

vscreen.bitmap[i] = malloc(height * sizeof(struct pixel));

然后一切都会好的。但...

..代码中还有许多其他问题。在new_screen中,您将分配一个指针数组,然后分别分配每一行。为什么不一次分配整个屏幕?

首先你可以将位图定义为struct pixel * bitmap; 并为结构分配一个空间 bitmap = malloc(width * height * sizeof(struct pixel));

然后你可以在(x,y)处访问像素作为位图[y * WIDTH + x]。您也可以在函数中隐藏它。

你的宽度和高度表示法的约定也很尴尬。在后面的循环中,您以通常的方式循环位图数组,但这会导致许多缓存未命中。由于您是按垂直顺序寻址数组。

另一个评论是关于循环的使用。你知道,有循环:for。在代码中使用它更有意义。

答案 1 :(得分:1)

所以你有:

typedef struct pixel{
    unsigned char b;
    unsigned char g;
    unsigned char r;
    float a;
};

struct virtual_screen{
    int layer;
    int width;
    int height;
    int opacity;
    struct pixel **bitmap;
};

typedef struct virtual_screen screen_t;

但是当你去分配bitmap的{​​{1}}成员时,你会这样做:

screen_t

vscreen.bitmap=malloc(width * sizeof(unsigned int *)); 来自哪里? unsigned int*的类型为bitmap

为了避免这些错误,最好这样做:

struct pixel**

同样,当你分配vscreen.bitmap=malloc(width * sizeof *vscreen.bitmap); 的元素时,你应该这样做:

vscreen.bitmap

(另外,你应该检查vscreen.bitmap[i] = malloc(height * sizeof *vscreen.bitmap[i]); 是否成功!)

作为旁注,我会说你的分配方案有点不寻常:你是按列分配,但通常是按行存储图像。我意识到你正在这样做,所以你可以使用(x,y)坐标作为数组下标,但是IMO最好不要对抗矩阵(行,列)约定。

答案 2 :(得分:0)

问题在于virtual_screen结构的位图声明。

试试这个:

struct pixel bitmap [] [];

然后,更正可能受此更改影响的代码部分。