You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取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赋值时,就会触发写入访问违例错误。

修复方案

  1. 在main函数中声明width、height、color三个变量,将它们的地址传递给PGM_FILE_READ_1D函数;
  2. 添加文件读取失败的判断逻辑,避免访问空指针导致崩溃;
  3. 新增内存释放逻辑,防止内存泄漏。

修复后的完整代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:40:41