将 int 成员添加到 C 结构会导致段错误

发布于 2024-07-14 05:57:56 字数 1771 浏览 6 评论 0原文

我仍在学习 C,并开始使用它来生成图像。 我不明白为什么我的一个程序会出现段错误。 这是源代码,减少到 40 行:

#include <stdio.h>
#include <stdlib.h>
struct color {
        unsigned char r, g, b;
};
struct image {
        int w, h/*, o*/;
        struct color **data;
};
int main() {
        // Declarations
        int x, y;
        struct color *black;
        struct image *img;
        // Set up color black
        black = (struct color *) malloc(sizeof(struct color *));
        black->r = 0;
        black->g = 0;
        black->b = 0;
        // Set up image img
        img = (struct image *) malloc(sizeof(struct image *));
        img->w = 1;
        img->h = 1;
        /*img->o = 0;*/
        img->data = (struct color **) malloc(img->h * sizeof(struct color *));
        for (y = 0; y < img->h; y++) {
                img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
        }
        // Fill in img with black
        for (x = 0; x < img->w; x++) {
                for (y = 0; y < img->h; y++) {
                        img->data[y][x].r = black->r;
                        img->data[y][x].g = black->g;
                        img->data[y][x].b = black->b;
                }
        }
        // Free black
        free(black);
        // Free img
        for (y = 0; y < img->h; y++)
                free(img->data[y]);
        free(img->data); // Segfaults
        free(img); // Also segfaults
        return 0;
}

它编译并运行良好(在 Ubuntu 上使用 gcc,在 Vista 上使用 Cygwin),但是取消注释处理 img->o 的两行会破坏它。 我有一种感觉,它与 上一个问题有关,但我正在 malloc'ing一切需要进行 malloc 的东西(我认为)。 任何帮助,将不胜感激。

I'm still learning C, and have started using it to generate images. I can't figure out why one of my programs is segfaulting. Here's the source code, cut down to 40 lines:

#include <stdio.h>
#include <stdlib.h>
struct color {
        unsigned char r, g, b;
};
struct image {
        int w, h/*, o*/;
        struct color **data;
};
int main() {
        // Declarations
        int x, y;
        struct color *black;
        struct image *img;
        // Set up color black
        black = (struct color *) malloc(sizeof(struct color *));
        black->r = 0;
        black->g = 0;
        black->b = 0;
        // Set up image img
        img = (struct image *) malloc(sizeof(struct image *));
        img->w = 1;
        img->h = 1;
        /*img->o = 0;*/
        img->data = (struct color **) malloc(img->h * sizeof(struct color *));
        for (y = 0; y < img->h; y++) {
                img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
        }
        // Fill in img with black
        for (x = 0; x < img->w; x++) {
                for (y = 0; y < img->h; y++) {
                        img->data[y][x].r = black->r;
                        img->data[y][x].g = black->g;
                        img->data[y][x].b = black->b;
                }
        }
        // Free black
        free(black);
        // Free img
        for (y = 0; y < img->h; y++)
                free(img->data[y]);
        free(img->data); // Segfaults
        free(img); // Also segfaults
        return 0;
}

It compiles and runs fine (using gcc on Ubuntu and on Vista with Cygwin), but uncommenting the two lines dealing with img->o breaks it. I have a feeling it's related to this previous question, but I'm malloc'ing everything that needs to be malloc'ed (I think). Any help would be appreciated.

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

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

发布评论

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

评论(4

一绘本一梦想 2024-07-21 05:57:56

您的 malloc 语句中有一个错误。 您正在分配指针而不是结构。 这仅提供 4 个字节的内存,而不是结构所需的实际大小。

black = malloc(sizeof(*black));

为指针分配内存时,您需要为所指向的对象分配内存,而不是指针的类型。 如果您只是如图所示编写 sizeof(*black),即使 black 的类型发生变化,您也将始终获得正确的类型。

There is a bug in your malloc statements. You are mallocing a pointer and not a struct. This gives you only 4 bytes of memory instead of the actual size required by your struct.

black = malloc(sizeof(*black));

When allocating memory for a pointer, you need to allocate memory for the thing being pointed at, not the type of the pointer. If you simply write sizeof(*black) as shown, you will always get the right type, even if the type of black changes.

扬花落满肩 2024-07-21 05:57:56

乍一看,您似乎使用了额外级别的指针间接寻址,这导致了段错误。 当您分配内存时,它是指向对象的指针,而不是指向对象指针的指针。 所以你将拥有:

img = (struct image *)malloc(sizeof(struct image))
img->o = 0

At first glance, it seems that you're using an additional level of pointer indirection, and that's causing the segfault. When you malloc memory, it's a pointer to the object, not a pointer to a pointer to an object. So you'll have:

img = (struct image *)malloc(sizeof(struct image))
img->o = 0
煞人兵器 2024-07-21 05:57:56

JaredPar 有正确的答案,但如果出现段错误,首先要做的就是在 valgrind 下运行程序。 对于处理此类问题有很大的帮助。

顺便说一句,我已经在这个错误上浪费了好几天的时间。 很高兴你在 C 编程职业生涯的早期就遇到了它,并且将来会一直留意它。

JaredPar has the right answer, but if you get a segfault, the first thing to do is run the program under valgrind. It is a huge help for dealing with problems like this.

BTW, I've wasted days on that exact bug. Be happy you ran into it early in your C programming career and will always watch out for it in the future.

慕烟庭风 2024-07-21 05:57:56

哎呀,代码被截断了; 我忘记转义小于号。 这里是:

#include <stdio.h>
#include <stdlib.h>
struct color {
    unsigned char r, g, b;
};
struct image {
    int w, h/*, o*/;
    struct color **data;
};
int main() {
    // Declarations
    int x, y;
    struct color *black;
    struct image *img;
    // Set up color black
    black = (struct color *) malloc(sizeof(struct color *));
    black->r = 0;
    black->g = 0;
    black->b = 0;
    // Set up image img
    img = (struct image *) malloc(sizeof(struct image *));
    img->w = 1;
    img->h = 1;
    /*img->o = 0;*/
    img->data = (struct color **) malloc(img->h * sizeof(struct color *));
    for (y = 0; y < img->h; y++) {
        img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
    }
    // Fill in img with black
    for (x = 0; x < img->w; x++) {
        for (y = 0; y < img->h; y++) {
            img->data[y][x].r = black->r;
            img->data[y][x].g = black->g;
            img->data[y][x].b = black->b;
        }
    }
    // Free black
    free(black);
    // Free img
    for (y = 0; y < img->h; y++)
        free(img->data[y]);
    free(img->data);
    free(img);
    // Return
    return 0;
}

Oops, the code was cut off; I forgot to escape a less-than sign. Here it is:

#include <stdio.h>
#include <stdlib.h>
struct color {
    unsigned char r, g, b;
};
struct image {
    int w, h/*, o*/;
    struct color **data;
};
int main() {
    // Declarations
    int x, y;
    struct color *black;
    struct image *img;
    // Set up color black
    black = (struct color *) malloc(sizeof(struct color *));
    black->r = 0;
    black->g = 0;
    black->b = 0;
    // Set up image img
    img = (struct image *) malloc(sizeof(struct image *));
    img->w = 1;
    img->h = 1;
    /*img->o = 0;*/
    img->data = (struct color **) malloc(img->h * sizeof(struct color *));
    for (y = 0; y < img->h; y++) {
        img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
    }
    // Fill in img with black
    for (x = 0; x < img->w; x++) {
        for (y = 0; y < img->h; y++) {
            img->data[y][x].r = black->r;
            img->data[y][x].g = black->g;
            img->data[y][x].b = black->b;
        }
    }
    // Free black
    free(black);
    // Free img
    for (y = 0; y < img->h; y++)
        free(img->data[y]);
    free(img->data);
    free(img);
    // Return
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文