我遇到这个问题。首先,这是我写的一个简单的图形库。
我正在做的是使用程序员选择的维度来声明多个“虚拟屏幕”。为此,我需要根据屏幕包含的像素数动态分配足够的内存。
分配这个内存的函数似乎只在我的程序中工作一次,然后每次调用它就失败(带有段错误)。我认为这个问题可能就是我在虚拟屏幕上传递的方式(screen_t
)。我实现它的方式是,函数new_screen
不返回指针,而是实际的屏幕本身。我想也许这是一个错误。此外,当一个函数(如set_current_screen
)需要一个屏幕作为其参数之一时,它会传递地址,如下所示:
set_current_screen(&screen_variable);
这是正确的方法吗?当我拨打new_screen
时,这是导致段错误的原因吗?
提前致谢。代码是一个头文件(非常不完整),一个c文件在一个屏幕上绘制一些rects,尝试创建另一个,获得段错误。他们在这里:
答案 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 [] [];
然后,更正可能受此更改影响的代码部分。