调用fread后奇怪的printf行为(Odd printf behaviour after calling fread)

我正在尝试设计一个将位图图像加载到内存并最终显示它的函数。 我正在使用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\nBMP Height: %dpx", bitmap->px_width, bitmap->px_height); fclose(bmp_file); return bitmap; } } fputs("File format not supported.\n", stderr); fclose(bmp_file); return NULL; } #endif

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

I am trying to devise a function that will load bitmap images into memory and ultimately display it. I am compiling the code with Watcom 16-bit C compiler with the target set to DOS. I am running the program in DOSBox. The code is as follows:

#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\nBMP Height: %dpx", bitmap->px_width, bitmap->px_height); fclose(bmp_file); return bitmap; } } fputs("File format not supported.\n", stderr); fclose(bmp_file); return NULL; } #endif

When you run this program it will output: "BMP width: %dpx\n" but nothing after the newline character?? I find this extremely odd. I have confirmed that none of the operations fail or set the errno and that px_height is actually set to it's appropiate value. Is this something any of you have experience with?

最满意答案

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

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

你真正需要的是什么

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

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

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

You're only malloc'ing enough space for a pointer with this line

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

what you really need is

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

Also, as mrbatch noted, you're using a 16 bit compiler and so attempting to read 4 bytes of data into 2 byte int variables. Make sure the sizeof() your types matches what you're reading, e.g. a long int

So - in general - you are corrupting both your stack and your heap by writing more data than you should, and you can expect your program to behave very oddly :)

更多推荐