调用fread后奇怪的printf行为

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调用fread后奇怪的printf行为相关的知识,希望对你有一定的参考价值。

我正在尝试设计一个将位图图像加载到内存中并最终显示它的函数。我正在使用Watcom 16位C编译器编译代码,目标设置为DOS。我在DOSBox中运行程序。代码如下:

#ifndef __BITMAP_H__
#define __BITMAP_H__

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

typedef struct DIB
{
    int header_size;
    int px_width;
    int px_height;
}DIB_t;

DIB_t *load_bitmap(char *file_name)
{
    FILE *bmp_file;
    DIB_t *bitmap;
    char garbage[4];
    int c, file_size, pixel_offset;

    bitmap = (DIB_t*)malloc(sizeof bitmap);

    if(!bitmap)
    {
        perror("malloc()");
        return NULL;
    }

    bmp_file = fopen(file_name, "rb");

    if(!bmp_file)
    {
        perror("fopen()");
        return NULL;
    }

    c = fgetc(bmp_file);

    if(c == 'B')
    {
        c = fgetc(bmp_file);

        if(c == 'M')
        {
            fread(&file_size, 4, 1, bmp_file);
            fread(garbage, 1, 4, bmp_file);
            fread(&pixel_offset, 4, 1, bmp_file);
            fread(&bitmap->header_size, 4, 1, bmp_file);
            fread(&bitmap->px_width, 4, 1, bmp_file);
            fread(&bitmap->px_height, 4, 1, bmp_file);
            printf("BMP width: %dpx
BMP Height: %dpx", bitmap->px_width, bitmap->px_height);
            fclose(bmp_file);
            return bitmap;
        }
    }

    fputs("File format not supported.
", stderr);
    fclose(bmp_file);
    return NULL;
}
#endif

当你运行这个程序时,它将输出:“BMP宽度:%dpx n”但在换行符后没有任何内容?我觉得这很奇怪。我已经确认没有任何操作失败或设置errno,并且px_height实际上设置为它的适当值。这是你们有经验的吗?

答案

你只是用这条线来指向足够的空间来指针

bitmap = (DIB_t*)malloc(sizeof(bitmap));

你真正需要的是什么

bitmap = (DIB_t*)malloc(sizeof(DIB_t));

另外,正如mrbatch所指出的那样,你使用的是16位编译器,因此尝试将4字节数据读入2字节int变量。确保sizeof()与您正在阅读的内容相匹配,例如:一个long int

所以 - 一般来说 - 你通过编写比你应该写的更多的数据来破坏你的堆栈和你的堆,你可以期望你的程序表现得非常奇怪:)

另一答案

除了Paul为你的sizeof纠正malloc的答案之外,尝试在你的声明中将你的int值更改为long(我假设你的代码对于包含4个字节值的位图是正确的)。 16位编译器中的int将是2个字节。你需要一个long(或等效的long int)4字节值。


As suggested in the comments, even better would be to include inttypes.h and use int32_t instead of int or long to ensure a 32-bit value.

以上是关于调用fread后奇怪的printf行为的主要内容,如果未能解决你的问题,请参考以下文章

使用制服时 Xamarin OpenGL 片段着色器的奇怪行为

C++ 中 operator= 的奇怪行为

遍历 C 指针列表:奇怪的 printf 行为

Seekbar进度drawable异常行为onPause

C++ while循环奇怪的行为

为啥在 putw 在 C 中扩展文件后使用 fread?