未处理的异常访问冲突写入位置

问题描述 投票:0回答:1

当我编译我的程序时,我得到了这个未处理的异常,我不明白或不知道如何修复。

My Code.exe中0x00007FF6DFF937FE抛出异常:0xC0000005:访问冲突写入位置0x000002E07396F000。

如果存在此异常的处理程序,则可以安全地继续该程序。

//main.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <string>
#include "Image.h"

Image readPPM(const char* file);
void writePPM(const Image &img, const char* file);

int main()
{

std::vector<Image> inputImages;
inputImages.resize(13);
Image *outputImage;

for (int x = 1; x < 14; x++)
{
    inputImages.push_back(Image(3264, 2448));
    inputImages[x] = readPPM(std::string("Images/ImageStacker_set1/IMG_" + std::to_string(x) + ".ppm").c_str());
}

outputImage = new Image(3264, 2448);
outputImage->pixels = new Image::Rgb[3264, 2448];

for (int x = 0; x < 3264 * 2448; x++) {
    float sumR = 0.f;
    float sumG = 0.f;
    float sumB = 0.f;

    for (int i = 0; i < 12; i++) {
        sumR += inputImages[i].pixels[x].r;
        sumG += inputImages[i].pixels[x].g;
        sumB += inputImages[i].pixels[x].b;
    }

    outputImage->pixels[x].r = sumR / 13;
    outputImage->pixels[x].g = sumG / 13;
    outputImage->pixels[x].b = sumB / 13;
}


writePPM(*outputImage, "testPPM.ppm");

return 0;
}

Image readPPM(const char *filename)
{
    //Remove this cout to prevent multiple outputs
    std::cout << "Reading image ..." << std::endl;
    std::ifstream ifs;
    ifs.open(filename, std::ios::binary);
    Image src;
    try {
        if (ifs.fail()) {
            throw("Can't open the input file - is it named correctly/is it in the right directory?");
    }
    std::string header;
    int w, h, b;
    ifs >> header;
    if (strcmp(header.c_str(), "P6") != 0) throw("Can't read the input file - is it in binary format (Has P6 in the header)?");
    ifs >> w >> h >> b;
    src.w = w;
    src.h = h;
    //std::cout << w << " " << h << std::endl;
    src.pixels = new Image::Rgb[w * h]; // this is throw an exception if bad_alloc 
    ifs.ignore(256, '\n'); // skip empty lines in necessary until we get to the binary data 
    unsigned char pix[3]; // read each pixel one by one and convert bytes to floats 
    for (int i = 0; i < w * h; ++i) {
        ifs.read(reinterpret_cast<char *>(pix), 3);
        src.pixels[i].r = pix[0] / 255.f;
        src.pixels[i].g = pix[1] / 255.f;
        src.pixels[i].b = pix[2] / 255.f;
    }
    ifs.close();
}
catch (const char *err) {
    fprintf(stderr, "%s\n", err);
    ifs.close();
}

//Confirm image read
//Delete this to prevent multiple lines output
std::cout << "Image read" << std::endl;
return src;
}

//Write data out to a ppm file
//Constructs the header as above
void writePPM(const Image &img, const char *filename)
{
//std::cout << filename << std::endl;
std::cout << "Writing image ..." << std::endl;
if (img.w == 0 || img.h == 0) { fprintf(stderr, "Can't save an empty image\n"); return; }
std::ofstream ofs;
try {
    ofs.open(filename, std::ios::binary); // need to spec. binary mode for Windows users 
    if (ofs.fail()) throw("Can't open output file");
    ofs << "P6\n" << img.w << " " << img.h << "\n255\n";
    //std::cout << "P6\n" << img.w << " " << img.h << "\n255\n";
    unsigned char r, g, b;
    // loop over each pixel in the image, clamp and convert to byte format
    for (int i = 0; i < img.w * img.h; ++i) {
        r = static_cast<unsigned char>(std::min(1.f, img.pixels[i].r) * 255);
        g = static_cast<unsigned char>(std::min(1.f, img.pixels[i].g) * 255);
        b = static_cast<unsigned char>(std::min(1.f, img.pixels[i].b) * 255);
        ofs << r << g << b;
    }
    ofs.close();
    //Confirm image write
    std::cout << "Image written" << std::endl;
}
catch (const char *err) {
    fprintf(stderr, "%s\n", err);
    ofs.close();
    }
}

image.h的

#pragma once
//*********************************************
//Image class to hold and allow manipulation of images once read into the 
code
//from https://www.scratchapixel.com/
//*********************************************
#include <cstdlib> 
#include <cstdio>

class Image
{
public:
    // Rgb structure, i.e. a pixel 
    struct Rgb
    {
        Rgb() : r(0), g(0), b(0) {}
        Rgb(float c) : r(c), g(c), b(c) {}
        Rgb(float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
        bool operator != (const Rgb &c) const
        {
            return c.r != r || c.g != g || c.b != b;
        }
        Rgb& operator *= (const Rgb &rgb)
        {
            r *= rgb.r, g *= rgb.g, b *= rgb.b; return *this;
        }
        Rgb& operator += (const Rgb &rgb)
        {
            r += rgb.r, g += rgb.g, b += rgb.b; return *this;
        }
        friend float& operator += (float &f, const Rgb rgb)
        {
            f += (rgb.r + rgb.g + rgb.b) / 3.f; return f;
        }
        float r, g, b;
    };

     Image() : w(0), h(0), pixels(nullptr) { /* empty image */ }
     Image(const unsigned int &_w, const unsigned int &_h, const Rgb &c = 
 kBlack) :
        w(_w), h(_h), pixels(NULL)
    {
        pixels = new Rgb[w * h];
        for (int i = 0; i < w * h; ++i)
            pixels[i] = c;
    }
    //copy constructor
    Image(const Image &im)
    {
        w = im.w;
        h = im.h;
        pixels = new Rgb[im.w * im.h];
        for (int i = 0; i < im.w * im.h; ++i)
            pixels[i] = im.pixels[i];
    }
    //copy assignment operator
    Image& operator=(const Image& other)
    {
        w = other.w;
        h = other.h;
        pixels = new Rgb[other.w * other.h];
        for (int i = 0; i < other.w * other.h; ++i)
             pixels[i] = other.pixels[i];

        return *this;

    }
    const Rgb& operator [] (const unsigned int &i) const
    {
        return pixels[i];
    }
    Rgb& operator [] (const unsigned int &i)
    {
        return pixels[i];
    }
    ~Image()
    {
        if (pixels != NULL) delete[] pixels;
        //delete[] pixels;
    }
    //unsigned int w, h; // Image resolution 
    int w, h; // Image resolution
    Rgb *pixels; // 1D array of pixels 
    static const Rgb kBlack, kWhite, kRed, kGreen, kBlue; // Preset colors 
};

const Image::Rgb Image::kBlack = Image::Rgb(0);
const Image::Rgb Image::kWhite = Image::Rgb(1);
const Image::Rgb Image::kRed = Image::Rgb(1, 0, 0);
const Image::Rgb Image::kGreen = Image::Rgb(0, 1, 0);
const Image::Rgb Image::kBlue = Image::Rgb(0, 0, 1);

这是导致问题的代码。在调试时,似乎这里的指针有问题:

outputImage->pixels[x].r = sumR / 13;
outputImage->pixels[x].g = sumG / 13;
outputImage->pixels[x].b = sumB / 13;

对不起,我真的无法提供其他任何东西,但我之前从来没有这样的错误所以我不知道从哪里开始修复它。

c++ pointers unhandled-exception
1个回答
0
投票

这里有一些不好的程度。但我相信你打算写的核心:

inputImages[x] = Image(3264, 2448);
inputImages[x].pixels = readPPM(std::string("Images/ImageStacker_set1/IMG_" + std::to_string(x) + ".ppm").c_str());

单步执行代码:

  • std::vector<Image> inputImages - 叶子inputImages大小为0
  • inputImages.resize(13); - 叶子inputImages大小为13默认构造Images
  • inputImages.push_back(Image(3264, 2448)); - 通过在尾端添加默认图像将inputImages的大小增加1,最终将inputImages的大小增加到26
  • inputImages[x] = readPPM(std::string("Images/ImageStacker_set1/IMG_" + std::to_string(x) + ".ppm").c_str()); - 修改Image'[1 - 12]中默认构造的inputImagess之一然后最终修改Image(3264, 2448)中的第一个inputImages

这意味着您至少有13个从未访问过的Image(3264, 2448)对象。由相关代码访问的第一个元素,inputImage[0]是默认构造的Image。除非readPPM返回带有分配的Image场的pixels,否则在Images [1 - 12]范围内没有inputImages可以支持进入他们的pixels场。

© www.soinside.com 2019 - 2024. All rights reserved.