为什么我在 C 中出现 seg 错误



https://github.com/KRegan82/Tinkering/blob/master/sierpinskiBMP.c

(代码检索于 2017-11-05 — 可能与原始代码不同,这是问题中要求代码的另一个原因。

#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>

// data types for the standard MS sruct values for the headers
typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;
//bmp file header struct
typedef struct
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
} __attribute__((__packed__))
BITMAPFILEHEADER;
//bmp info header struct
typedef struct
{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} __attribute__((__packed__))
BITMAPINFOHEADER;
//bmp pixel struct
typedef struct
{
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
// this program is designed to 'build' a sierpinski triangle of n layers given the users input. triangle built from top down using 2 x 2 pixel structure
// the structs above are completely 'borrowed' from the team at harvards cs50 class, whose mobile IDE is also wehre I wrote this
// and a special thank you to Irene Naya and Aditya Singhania two strangers on facebook for whom I couldn't have made this without
int main(void)
{
    //prompt for and store height (in 2x2 pixel size)
    fprintf(stderr, "How many layers do you want? ");
    int n = get_int();
    //setup paramaters to write to .bmp file and filename
    char ofName[21];
    sprintf(ofName,"sierpinski%05i.bmp",n);
    FILE *outfile = fopen(ofName,"w");
    // setup file header and info header assignments
    BITMAPFILEHEADER bf;
    BITMAPINFOHEADER bi;
    //calculate header and header info values to write using structs in bmp.h
    bi.biWidth = (n * 2) + 4;
    bi.biHeight = 0 -((n * 2) + 4);
    //calculate padding that will be needed
    int pad = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    // assign new image size
    bi.biSizeImage = abs(bi.biHeight) * ((bi.biWidth * sizeof(RGBTRIPLE)) + pad);
    // assign new file header parameters
    bf.bfType = 0x4d42;
    bf.bfReserved1 = 0;
    bf.bfReserved2 = 0;
    bf.bfOffBits = 0x36;
    //assign new info header parameters
    bi.biSize = 0x28;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    bi.biCompression = 0;
    bi.biXPelsPerMeter = 0xb12;
    bi.biYPelsPerMeter = 0xb12;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
    // assign new file size
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outfile);
    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outfile);
    //necessary variables for triangle algorithm
    long long body[n][n];
    int print = 0;
    //create rgp triple for manipulation
    RGBTRIPLE pixel;
    //add buffer lines to top of .bmp
    for(int i = 0; i< ((n * 2) + 4); i++)
    {
        pixel.rgbtRed = 0xff;
        pixel.rgbtBlue = 0xff;
        pixel.rgbtGreen = 0xff;
        fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
    }
    //add padding in if necessary
    for (int l = 0; l < pad; l++)
    {
        fputc(0x00, outfile);
    }
    // second layer of top buffer lining
    for(int i = 0; i< ((n * 2) + 4); i++)
    {
        pixel.rgbtRed = 0xff;
        pixel.rgbtBlue = 0xff;
        pixel.rgbtGreen = 0xff;
        fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
    }
    //add padding in if necessary
    for (int l = 0; l < pad; l++)
    {
        fputc(0x00, outfile);
    }
    // iterate over the area and print necessary digits
    for(int i = 0; i < n ; i++)
    {
        // blank space that borders triangle value
        int blankCount = (n + 1) - i;
        //write blank space surrounding start of triangle
        for(int j = 0; j < blankCount; j++ )
        {
            pixel.rgbtRed = 0xff;
            pixel.rgbtBlue = 0xff;
            pixel.rgbtGreen = 0xff;
            fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
        }
        //draw first line of this rows triangle values
        for(int j = 0; j<=i; j++)
        {

            if (j == 0 || i == j)
            {
                print = 1;
                body[i][j] = 1;
            }
            else if( body[i-1][j-1] + body[i-1][j] == 2 || body[i-1][j-1] + body[i-1][j] == 0)
            {
                print = 0;
                body[i][j] = 0;
            }
            else if(body[i-1][j-1] + body[i-1][j] == 1 )
            {
                print = 1;
                body[i][j] = 1;
            }
            if ( print == 0)
            {
                pixel.rgbtRed = 0xff;
                pixel.rgbtBlue = 0xff;
                pixel.rgbtGreen = 0xff;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
            else if (print == 1)
            {
                pixel.rgbtRed = 0x00;
                pixel.rgbtBlue = 0x00;
                pixel.rgbtGreen = 0x00;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
        }
        // proceeding blank space bordering back end of triangle
        for(int j = 0; j < blankCount; j++ )
            {
                pixel.rgbtRed = 0xff;
                pixel.rgbtBlue = 0xff;
                pixel.rgbtGreen = 0xff;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
        //add back in if necessary
        for (int l = 0; l < pad; l++)
        {
            fputc(0x00, outfile);
        }
        //this is really just a second iteration of drawing the same row. each row has to be drawn twice because each element is 2 pixels by two pixels
        for(int j = 0; j <blankCount ; j++ )
        {
            pixel.rgbtRed = 0xff;
            pixel.rgbtBlue = 0xff;
            pixel.rgbtGreen = 0xff;
            fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
        }
        for(int j = 0; j<=i; j++)
        {

            if (j == 0 || i == j)
            {
                print = 1;
                body[i][j] = 1;
            }
            else if( body[i-1][j-1] + body[i-1][j] == 2 || body[i-1][j-1] + body[i-1][j] == 0)
            {
                print = 0;
                body[i][j] = 0;
            }
            else if(body[i-1][j-1] + body[i-1][j] == 1 )
            {
                print = 1;
                body[i][j] = 1;
            }
            if ( print == 0)
            {
                pixel.rgbtRed = 0xff;
                pixel.rgbtBlue = 0xff;
                pixel.rgbtGreen = 0xff;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
            else if (print == 1)
            {
                pixel.rgbtRed = 0x00;
                pixel.rgbtBlue = 0x00;
                pixel.rgbtGreen = 0x00;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
        }
        for(int j = 0; j < blankCount; j++ )
            {
                pixel.rgbtRed = 0xff;
                pixel.rgbtBlue = 0xff;
                pixel.rgbtGreen = 0xff;
                fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
            }
        //add padding in if necessary
        for (int l = 0; l < pad; l++)
        {
            fputc(0x00, outfile);
        }
    }
    // add buffer lines to bottom of .bmp
    for(int i = 0; i< ((n * 2) + 4); i++)
    {
        pixel.rgbtRed = 0xff;
        pixel.rgbtBlue = 0xff;
        pixel.rgbtGreen = 0xff;
        fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
    }
    //add padding in if necessary
    for (int l = 0; l < pad; l++)
    {
        fputc(0x00, outfile);
    }
    for(int i = 0; i< ((n * 2) + 4); i++)
    {
        pixel.rgbtRed = 0xff;
        pixel.rgbtBlue = 0xff;
        pixel.rgbtGreen = 0xff;
        fwrite(&pixel, sizeof(RGBTRIPLE), 1, outfile);
    }
    //add padding in if necessary
    for (int l = 0; l < pad; l++)
    {
        fputc(0x00, outfile);
    }
    // just tidying up here
    fclose(outfile);
    return 0;
}

我正在上CS50课,并编写了这个程序来将Sierpinski三角形输出到用户给定高度的.bmp文件中。它可以很好地生成最多超过 512 行的任何内容,但在 1024(下一个完整的三角形高度)处,我遇到了 seg 错误。

不知道为什么会发生这种情况,是因为我要从堆栈而不是堆中分配内存吗?任何帮助将不胜感激。

下面是一段代码,我在其中初始化跟踪每个像素应包含的值的数组。

 long long body[n][n];

我把它改成了很长的希望能解决问题,但显然这是另一回事。困惑。

你的 body[n][n] 数组太大,无法在堆栈上分配。您可以将其分配到堆上,而受大小的限制要小得多。有关如何动态分配 2D 数组的信息,请参阅前面的答案:在函数 C 中分配内存 2d 数组

相关内容

  • 没有找到相关文章

最新更新