【发布时间】:2017-12-20 17:07:23
【问题描述】:
当我编译我的程序时,我得到了这个我不理解或不知道如何修复的未处理异常。
在我的 0x00007FF6DFF937FE 处抛出异常 Code.exe: 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();
}
}
图像.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;
抱歉,我真的无法提供任何其他内容,但我以前从未遇到过这样的错误,所以我不知道从哪里开始修复它。
【问题讨论】:
-
readPPM 究竟返回了什么?
-
resize和push_back是不健康的组合。你的意思是reserve? -
@newbie123 --
Vector subscript out of range。那是因为您调整了向量的大小以容纳 13 个项目,并且您的第一个for循环尝试访问超出范围的 inputImages[13]。索引范围从0到n-1,其中n是条目数。不知道这样说要简单得多。 -
@newbie123 你没看到
new Image::Rgb[3264, 2448];这里的错误吗? -
@newbie123 建议 -- 如果 1) 自分配完成和 2) 如果
new抛出异常,则Image的复制/赋值运算符将惨遭失败。请改用copy / swap成语。
标签: c++ pointers unhandled-exception