读取PGM文件提取隐写文本时触发写入访问违例(空指针)求助
问题与修复方案
问题概述
作业要求读取.pgm文件,通过解码每个字节的最低有效位提取隐藏文本。使用教授提供的读写代码时,读取文件阶段触发错误:Exception thrown: write access violation. Variable was nullptr,问题出在color变量的写入操作上。已知提取隐藏文本的逻辑,但IO操作环节一直出错。(注:提供的.pgm文件已重命名为.png,下载后需改回.pgm格式)
错误原因
查看main函数中的调用代码:
uchar* image = PGM_FILE_READ_1D("./hw10.pgm", 876, 594, 0);
PGM_FILE_READ_1D函数的Width、Height、color参数要求是指针类型,目的是通过指针将读取到的图像宽、高、色彩模式值写入外部变量。但此处直接传递了字面量876、594、0,这些字面量并非有效指针(本质是非法内存地址或nullptr),函数内部尝试给*Width、*Height、*color赋值时,就会触发写入访问违例错误。
修复方案
- 在
main函数中声明width、height、color三个变量,将它们的地址传递给PGM_FILE_READ_1D函数; - 添加文件读取失败的判断逻辑,避免访问空指针导致崩溃;
- 新增内存释放逻辑,防止内存泄漏。
修复后的完整代码
#include <stdlib.h> #include <stdio.h> #include <string.h> typedef unsigned char uchar; /****************************************/ /* Clear PGM (XV) comments. */ /****************************************/ void pgmCommentClear(FILE* disk) { uchar ch; fread(&ch, 1, 1, disk); if (ch != '#') { fseek(disk, -1, SEEK_CUR); return; } do { while (ch != '\n') fread(&ch, 1, 1, disk); } while (ch == '#'); pgmCommentClear(disk); } /****************************************/ /* Read PGM formatted image (1D array). */ /****************************************/ uchar* PGM_FILE_READ_1D(char* FileName, int* Width, int* Height, int* color) { int pmax; char ch; char type[3]; uchar* Image; FILE* disk; if ((disk = fopen(FileName, "rb")) == NULL) { printf("Failed to open file!\n"); return NULL; } fscanf(disk, "%s", type); if (!strcmp(type, "P6")) *color = 1; else *color = 0; fread(&ch, 1, 1, disk); pgmCommentClear(disk); fscanf(disk, "%d", Width); fscanf(disk, "%d", Height); fscanf(disk, "%d", &pmax); fread(&ch, 1, 1, disk); if (*color == 1) { Image = (uchar*)calloc(*Height * *Width * 3, sizeof(uchar)); fread(Image, 1, (*Height * *Width * 3), disk); } else { Image = (uchar*)calloc(*Height * *Width, sizeof(uchar)); fread(Image, 1, (*Height * *Width), disk); } fclose(disk); return Image; } /****************************************/ /* Write PGM formatted image (1D array).*/ /****************************************/ void PGM_FILE_WRITE_1D(char* FileName, uchar* Image, int Width, int Height, int color) { FILE* disk; disk = fopen(FileName, "wb"); if (color == 1) fprintf(disk, "P6\n"); else fprintf(disk, "P5\n"); fprintf(disk, "%d %d\n", Width, Height); fprintf(disk, "255\n"); if (color == 1) { fwrite(Image, 1, (Height * Width * 3), disk); } else { fwrite(Image, 1, (Height * Width), disk); } fclose(disk); } int main(int argc, char const* argv[]) { int width, height, color; uchar* image = PGM_FILE_READ_1D("./hw10.pgm", &width, &height, &color); if (image == NULL) { return 1; } // 此处可添加提取隐藏文本的逻辑 printf("Image width: %d, height: %d, color mode: %d\n", width, height, color); printf("First pixel value: %d\n", *image); // 释放动态分配的内存 free(image); return 0; }
额外说明
- 修复后的代码通过
&width、&height、&color传递变量地址,确保函数内部能正确写入图像参数; - 新增的空指针判断避免了文件读取失败后继续操作导致的崩溃;
free(image)语句释放了calloc分配的内存,防止内存泄漏。
内容的提问来源于stack exchange,提问作者FunkyMunky
相关产品推荐
相关产品推荐

