c - bmp 文件错误 - 项目 2017.1.exe : 0xC0000005: Access violation writing location 0xCDCDCDCD 中 0x0FDD053F (ucrtbased.dll) 抛出异常

标签 c rgb bmp

在此代码中,我尝试从 bmp 文件中获取每个像素中的第一个字节,其中每个像素的 RGB 值相同(如 ff ff ff),并将这些值放入矩阵中以进行进一步操作。当调试器达到“从每个像素获取第一个字节”时,调试过程终止 并出现“项目 2017.1.exe 中的 0x0FDD053F (ucrtbased.dll) 抛出异常:0xC0000005:访问冲突写入位置 0xCDCCDCD”。有什么问题吗?(这是我第一次使用 bmp)感谢您的帮助!

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

main() {
    int width, height, w_count, h_count, padding;
    int **pix_mat;
    int a;
    FILE * dust_pic;
    fopen_s(&dust_pic, "d2.bmp", "rb");
    if (!dust_pic)
        printf_s("not found");
    fseek(dust_pic, 18, SEEK_SET);
    fread(&width, sizeof(int), 1, dust_pic);// getting width
    fread(&height, sizeof(int), 1, dust_pic);// getting height
    // FIND PADDING
    a = width;
    if (a % 4 != 0)
        padding = 4 - (a % 4);
    else
    padding = 0;

    //making matrix for pixels
    pix_mat = (int**)malloc(sizeof(int*)*height);
    for (h_count = 0; h_count < height; h_count++)
        pix_mat[h_count] = (int*)malloc(sizeof(int)*width);

    fseek(dust_pic, 54, SEEK_SET);
    // getting the first byte from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            fread(pix_mat[w_count][h_count], sizeof(char), 1, dust_pic);
            fseek(dust_pic, 2, SEEK_CUR);
        }
        fseek(dust_pic, padding, SEEK_CUR);
    }
    fclose(dust_pic);
    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf_s("[%d],[%d]=%d  ", w_count, h_count, pix_mat[w_count][h_count]);
        printf("\n");
    }
    // free array
    for (h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);
}

最佳答案

以下建议代码:

  1. 干净地编译
  2. 正确检查错误
  3. 在发生任何错误事件后退出之前正确清理
  4. 从文件中正确读取正确大小的数据并将该数据保存到正确声明的数组中
  5. 正确引用内存中像素矩阵的行和列
  6. 不纠正有关像素宽度、文件中像素偏移等的假设。

现在是代码

#include <stdio.h>  // fopen(), fclose(), perror(), fseek(), SEEK_SET
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), calloc(), free()

// prototypes
void cleanup( FILE *dust_pic, size_t height, char **pix_mat );


int main( void )
{
    size_t width, height, w_count, h_count;
    long padding;
    char **pix_mat;

    FILE * dust_pic;
    dust_pic = fopen("d2.bmp", "rb");
    if (!dust_pic)
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen_s successful

    fseek(dust_pic, 18, SEEK_SET);
    // check for error

    if( 1 != fread(&width, sizeof(int), 1, dust_pic) )// getting width
    {
        perror( "fread for width of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    if( 1 != fread(&height, sizeof(int), 1, dust_pic) )// getting height
    {
        perror( "fread for height of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    // calculate PADDING
    if ( width % 4 != 0)
        padding = (long)(4 - (width % 4));
    else
        padding = 0;

    //making matrix for pixels
    pix_mat = calloc(height, sizeof(char*));
    // check for malloc status
    if( !pix_mat )
    {
        perror( "calloc for array of pointers to char failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    for (h_count = 0; h_count < height; h_count++)
    {
        pix_mat[h_count] = malloc(sizeof(char)*width);
        // check for malloc status
        if( !pix_mat[h_count] )
        {
            perror( "malloc failed" );
            fclose( dust_pic );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful
    }

    // jump to beginning of pixel data in file
    if( -1 == fseek(dust_pic, 54, SEEK_SET) )
    {
        perror( "fseek to start of pixel data failed" );
        cleanup( dust_pic, height, pix_mat );
        exit( EXIT_FAILURE );
    }

    // implied else, fseek successful

    // get the first byte (red) from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            if( 1 != fread( &((pix_mat[h_count])[w_count]), sizeof(char), 1, dust_pic) )
            {
                perror( "fread of 'red' pixel value failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fread successful

            if( -1 == fseek(dust_pic, 2, SEEK_CUR) )
            {
                perror( "fseek to skip green/blue pixels failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fseek successful
        }

        if( -1 == fseek(dust_pic, padding, SEEK_CUR) )
        {
            perror( "fseek to skip padding failed" );
            cleanup( dust_pic, height, pix_mat );
            exit( EXIT_FAILURE );
        }

        // implied else, fseek successful
    }


    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf("[%lu],[%lu]=%3.3d  ", h_count, w_count, (pix_mat[h_count])[w_count]);
        printf("\n");
    }

    cleanup( dust_pic, height, pix_mat );
} // end function: main


void cleanup( FILE *dust_pic, size_t height, char **pix_mat )
{
    // free array
    for (size_t h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);

    fclose( dust_pic );
} // end function: cleanup

关于c - bmp 文件错误 - 项目 2017.1.exe : 0xC0000005: Access violation writing location 0xCDCDCDCD 中 0x0FDD053F (ucrtbased.dll) 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44372470/

相关文章:

android - 如何将原始 RGB 帧缓冲区文件转换为可视格式?

c - Realloc 使我的程序崩溃

c++ - C语言在不同架构上的文件操作

c - window C : LoadBitmap() function is not working

c++ - 将 RGB 图像转换为 3 个 HSI 输出

java - 在java中仅使用灰度值数组绘制图像

c++ - 在 Arduino 上使用最少数量的 PWM 引脚连接多个 RGB LED?

c - 没有 `...` 的可变参数函数

file - bmp 文件比较?

c - 从 BMP 文件读取到 C 中的 BMP 头结构