【问题标题】:Error with bmp file-Exception thrown at 0x0FDD053F (ucrtbased.dll) in project 2017.1.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD在项目 2017.1.exe 中的 0x0FDD053F (ucrtbased.dll) 处引发 bmp 文件异常错误:0xC0000005:访问冲突写入位置 0xCDCDCDCD
【发布时间】:2017-06-05 15:35:52
【问题描述】:

在这段代码中,我尝试从每个像素的 RGB 值相同(如 ff ff ff)的 bmp 文件中获取每个像素中的第一个字节,并将这些值放入矩阵中以进行进一步操作。当调试器到达“从每个像素获取第一个字节”时,调试过程终止 并出现“在项目 2017.1.exe 中的 0x0FDD053F (ucrtbased.dll) 处引发异常:0xC0000005:访问冲突写入位置 0xCDCDCDCD”。有什么问题?(这是我第一次使用 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);
}

【问题讨论】:

  • CDCDCDCD 是一个幻数,它是在调试版本中 malloc() 分配的内存内容。所以您知道您正在阅读未初始化的 pix_mat 内容。你是,你颠倒了索引。除了推理之外,您还可以通过 first 调试这样的代码,使其在一个很小的位图上运行。从 1x1 开始,然后是 2x1,然后是 1x2,到那时你会发现 98% 的问题。
  • 能否请您多解释一下为什么会出现问题,我真的不明白
  • 应该是 pix_mat[h_count][w_count]。你扭转了这一点。
  • @HansPassant : 它还需要一个 & 符号。
  • main() 函数只有两个有效签名,无论 Visual Studio 允许什么。 1)int main( int argc, char *argv[] ) 和 2)int main( void )。请注意,两个签名的返回类型均为 int

标签: c rgb bmp


【解决方案1】:

以下建议的代码:

  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

【讨论】:

    猜你喜欢
    • 2016-11-12
    • 1970-01-01
    • 2020-08-09
    • 2021-02-14
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2018-06-26
    相关资源
    最近更新 更多