C 用编译器优化联合中的分段错误

C 用编译器优化联合中的分段错误,c,segmentation-fault,return,C,Segmentation Fault,Return,我的代码使用并集来表示RGB像素。它在调试模式下工作得很好,但启用了编译器优化后,它会自动排除故障 您可以在下面看到复制错误的简化测试代码。我的系统是带有GCC4.8.2的Ubuntu #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> union Pixel { uint32_t color; uint8_t at[4]

我的代码使用并集来表示RGB像素。它在调试模式下工作得很好,但启用了编译器优化后,它会自动排除故障

您可以在下面看到复制错误的简化测试代码。我的系统是带有GCC4.8.2的Ubuntu

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

union Pixel {
    uint32_t color;
    uint8_t at[4];
};

typedef struct Screen {
    union Pixel *pixels;
    int width;
    int height;
    int rPosition;
    int gPosition;
    int bPosition;
} *Screen;

Screen ScreenCreate(int width, int height, uint32_t rPosition, uint32_t gPosition, uint32_t bPosition) {
    Screen this = malloc(sizeof *this);
    this->pixels = malloc(width * height * sizeof this->pixels[0]);
    this->width = width;
    this->height = height;
    this->rPosition = rPosition;
    this->gPosition = gPosition;
    this->bPosition = bPosition;
}

void ScreenDelete(Screen this) {
    free(this->pixels);
    free(this);
}

void ScreenFill(Screen this, uint8_t r, uint8_t g, uint8_t b) {
    union Pixel pixel;
    pixel.color = 0;
    pixel.at[this->rPosition] = r;
    pixel.at[this->gPosition] = g;
    pixel.at[this->bPosition] = b;
    for (int i = 0; i < this->width * this->height; i += 1) {
        this->pixels[i].color = pixel.color;
    }
}

int main(void) {
    Screen screen = ScreenCreate(500, 500, 2, 1, 0);
    ScreenFill(screen, 0xff, 0xff, 0xff);
    ScreenDelete(screen);
    return 0;
}
#包括
#包括
#包括
#包括
联合像素{
uint32_t颜色;
[4]处的uint8_t;
};
类型定义结构屏幕{
联合像素*像素;
整数宽度;
内部高度;
整合;
int-gPosition;
内倾位置;
}*屏幕;
屏幕创建(内部宽度、内部高度、uint32位置、uint32位置、uint32位置){
Screen this=malloc(sizeof*this);
此->像素=malloc(宽度*高度*大小此->像素[0]);
这个->宽度=宽度;
这个->高度=高度;
此->位置=位置;
此->gPosition=gPosition;
此->位置=位置;
}
作废屏幕删除(此屏幕){
自由(此->像素);
免费(这个);
}
无效屏幕填充(此屏幕、uint8\u t r、uint8\u t g、uint8\u t b){
联合像素;
pixel.color=0;
像素。在[this->rPosition]=r;
像素。在[this->gPosition]=g;
像素.at[此->b位置]=b;
对于(int i=0;iwidth*this->height;i+=1){
这->像素[i].color=pixel.color;
}
}
内部主(空){
屏幕=屏幕创建(500500,2,1,0);
屏幕填充(屏幕,0xff,0xff,0xff);
屏幕删除(屏幕);
返回0;
}
在您的
屏幕创建()
函数中,您忘记了
返回语句。因此,您的代码会产生未定义的行为

最后一行应该是

 return this;
相关:根据
C11
标准,第§6.9.1章,功能定义,第12段

如果到达了终止函数的
}
,并且调用方使用了函数调用的值,则行为未定义

因此,使用
main()
中的
屏幕
会导致


故事的寓意:启用编译器警告并注意它们。< /p> @ XVIE77因为它调用。而且我非常确信,如果你用“代码> GCC墙-WORT < /CODE”编译,编译器会警告你。@ XIV77不可定义的行为可以包括预期的工作。我不建议使用C++关键词(如<代码> < <代码> >)在C代码中(特别是在头文件中)。

typedef struct Screen*Screen,这真是令人困惑。最好不要使用指针typedef;但如果必须,请给他们一个不同于他们所指向类型名称的名称。