遇到一个非常烦人的分段错误...在 C 中分配二维数组

发布于 2024-09-25 15:05:41 字数 689 浏览 0 评论 0原文

我在这方面遇到了一点麻烦。首先,这是我正在编写的一个简单的图形库。

我正在做的是使声明多个“虚拟屏幕”成为可能,其尺寸由程序员选择。为此,我需要根据屏幕将包含的像素数动态分配足够的内存。

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

set_current_screen(&screen_variable);

这是正确的方法吗?这是我调用 new_screen 时导致段错误的原因吗?

提前致谢。该代码是一个头文件(非常不完整),而 ac 文件在一个屏幕上绘制一些矩形,尝试创建另一个,出现段错误。它们是:

hgl.h

main.c

I'm having a little trouble with this. First of all, this is for a simple graphics library that I was writing.

What I'm doing is making it possible to declare multiple "virtual screens", with dimensions of the programmer's choice. For this, I need to dynamically allocate enough memory based on the number of pixels the screen will contain.

The function that allocates this memory seems to work only once in my program, then fails (with a segfault) every other time I call it. I think the issue may be the way I'm passing around the virtual screen (screen_t). The way I implemented it, was that the function new_screen returns not a pointer, but the actual screen itself. I'm thinking maybe that was a mistake. Additionally, when a function, such as set_current_screen needs a screen as one of its arguments, it's passed the address, like this:

set_current_screen(&screen_variable);

Is this the right way to go about that? Is this what's causing the segfault when I call new_screen?

Thanks in advance. The code is a header file (very incomplete), and a c file that draws some rects on one screen, tries to make another, gets a segfault. Here they are:

hgl.h

main.c

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七禾 2024-10-02 15:05:41

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

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

既然您已经分配了一个指向结构像素数组的指针,为什么您会获得 int 的大小。您应该将其更改为以下内容:

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

那么一切都应该没问题。但是......

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

首先,您可以将位图定义为 struct Pixel *bitmap;
并为该结构分配一个空间:
位图 = malloc(宽度 * 高度 * sizeof(结构像素));

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

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

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

First of all, your code is not SEGFAULT'ing in the second new_screen() call. You mislead all of us :) Code crashes when you try to access it. Your main problem lies on this line:

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

Since you have allocated a pointer to an array of struct pixel's, why do you get the size of an int. You should change it to the following:

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

Then everything should be OK. But...

..There are many other problems in the code as well. In new_screen you are allocating an array of pointers, then each row separately. Why not allocate the whole screen at once?

First you can define bitmap as, struct pixel *bitmap;
And allocate a space for the struct as
bitmap = malloc(width * height * sizeof(struct pixel));

Then you can acces a pixel at (x,y) as bitmap[y*WIDTH+x]. You can hide this in a function as well.

Also your convention of width then height notation is quite awkward. In the later loops you are looping the bitmap array in the usual way but this causes many cache misses. Since you are addressing the array in vertical order.

Another remark is on the use of loops. You know, there is loop for that: for. It makes more sense to use for in your cases in the code.

辞别 2024-10-02 15:05:41

所以你有:

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;

但是当你去分配screen_tbitmap成员时,你会:

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]);

此外,您应该检查 malloc 成功!)

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

So you have:

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;

But when you go to allocate the bitmap member of the screen_t, you do:

vscreen.bitmap=malloc(width * sizeof(unsigned int *));

Where did unsigned int* come from? bitmap is of type struct pixel**.

To avoid these kinds of mistakes, it's better to do:

vscreen.bitmap=malloc(width * sizeof *vscreen.bitmap);

And similarly, when you allocate the elements of vscreen.bitmap, you should do:

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

(Also, you should check that malloc succeeded!)

As a side note, I'll say that your allocation scheme is a bit unusual: you're allocating by columns, but typically images are stored by rows. I realize you're doing this so you can use (x, y) coordinates for the array subscripts, but IMO it's better not to fight the matrix (row, column) convention.

故事还在继续 2024-10-02 15:05:41

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

试试这个:

struct Pixel bitmap[][];

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

The problem lies at the bitmap declaration at the virtual_screen struct.

Try this:

struct pixel bitmap[][];

Then, correct the parts of the code that may be affected by this change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文