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

xiv*_*r77 2 c return segmentation-fault

我的代码使用union来表示RGB像素.它在调试模式下运行良好,但启用了编译器优化后,会出现段错误.

您可以在下面看到简化的测试代码来重现错误.我的系统是Ubuntu和GCC4.8.2.

#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;
}
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 7

在你的ScreenCreate()功能中,你忘记了一个return陈述.因此,您的代码会产生未定义的行为.

最后一行应该是

 return this;
Run Code Online (Sandbox Code Playgroud)

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

如果}终止了函数,并且调用者使用了函数调用的值,则行为是未定义的.

所以,使用screenin main()会导致未定义的行为.

故事的道德:启用编译器警告并注意它们.

  • @ xiver77因为它调用了[未定义的行为](https://en.wikipedia.org/wiki/Undefined_behavior). (3认同)
  • 而且我很确定如果你使用`gcc -Wall -Wextra`进行编译,编译器会警告你. (3认同)