c++ - 复制构造函数中的段错误

标签 c++ class copy-constructor

我正在做一项作业,其中我们使用“Image”类来操作 *.ppm 图像。它会编译,然后在调用复制构造函数时出现段错误。这是:

Image::Image(const Image & imageToCopy) {
fileType = imageToCopy.fileType;
width = imageToCopy.width;
height = imageToCopy.height;
maxColor = imageToCopy.maxColor;

image = new int *[height];

for(int i=0; i < height; i++) {
    image[i] = new int [width];
    for(int j=0; j < width; j++) {
    image[i][j] = imageToCopy.image[i][j];
    }
}
}

这样调用:

Image image2(image1);

我有点不明白为什么会发生这种情况。我不知道出了什么问题,因为代码几乎与我的构造函数相同,并且运行良好。唯一的区别是我有

image[i][j] = imageToCopy.image[i][j];

而不是

imageInputStream >> image[i][j];

想法?谢谢

编辑:构造函数如下:

Image::Image(const char* filename) {
    ifstream imageInputStream;
    imageInputStream.open(filename);

    imageInputStream >> fileType;
    imageInputStream >> width;
    imageInputStream >> height;
    imageInputStream >> maxColor;

    image = new int *[height];

    for(int i=0; i < height; i++) {
        image[i] = new int [width];
        for(int j=0; j < width; j++) {
            imageInputStream >> image[i][j];
        }
    }

    imageInputStream.close();
}

最佳答案

在没有看到完整代码的情况下,这只是一个猜测,但是如果您创建了复制构造函数和析构函数,但没有复制赋值运算符,那么如果您尝试使用赋值,则可能会遇到与此完全相同的段错误。

您可能不认为自己在任何地方做作业,但除非您了解 C++ 的所有规则(即使是专家也不知道,更不用说新学生了),否则很难确定。最简单的查找方法是声明一个私有(private)赋值运算符并且不定义它(或者,如果您使用的是 C++11,则声明它已删除),然后查看是否出现编译错误。

例如:

struct Image {
  int width_, height_;
  int **image_;
  Image(int width, int height) : width_(width), height_(height),
                                 image_(0) {
    image_ = new int *[height_];
    for (int i = 0; i != height_; ++i) {
      image_[i] = new int[width_];
      for (int j = 0; j != width_; ++j) {
        image_[i][j] = 1;
      }
    }
  }

  Image(const Image& rhs) : width_(rhs.width_), height_(rhs.height_),
                            image_(0) {
    image_ = new int*[height_];
    for (int i = 0; i != height_; ++i) {
      image_[i] = new int[width_];
      for (int j = 0; j != width_; ++j) {
        image_[i][j] = rhs.image_[i][j];
      }
    }
  }

  /* uncomment to uncrash
  Image& operator=(const Image& rhs) {
    if (this == &rhs) return *this;
    for (int i = 0; i != height_; ++i) {
      delete [] image_[i];
    }
    delete [] image_;
    image_ = new int*[height_];
    for (int i = 0; i != height_; ++i) {
      image_[i] = new int[width_];
      for (int j = 0; j != width_; ++j) {
        image_[i][j] = rhs.image_[i][j];
      }
    }
    return *this;
  }
  */

  ~Image() {
    for (int i = 0; i != height_; ++i) {
      delete [] image_[i];
    }
    delete [] image_;
  }
};

int main(int, char*[]) {
  Image img(200, 300);
  Image img2(img);
  Image img3(100, 200);
  img3 = img2;
  return 0;
}

正如注释所暗示的,如果您取消注释复制赋值运算符,整个事情就会起作用。

如果这是您的问题,请阅读三法则( WikipediaWard's Wiki )。

关于c++ - 复制构造函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13183941/

相关文章:

c++ - 编译器可以用直接初始化代替复制初始化吗?

c++ - 为什么抛出引用调用复制构造函数的异常?

java - 如何使用 JNI 在 Android 中包含不可修改的原生 C++?

c++ - 以迭代方式复制二叉树

c++ - boost::unordered_map.emplace(Args&&... args) 如何工作?

python - 我在实例化期间传递给类的参数/kwargs __init__ 被忽略

c++ - 为类存储指向另一个类的指针复制构造函数析构函数和赋值运算符

c++ - OpenGL - PBuffer 渲染到纹理

class - 我可以在 Scala 类中定义无名方法吗?

python 类: questions about creating instances