1 year ago

#340028

test-img

Kleber Mota

Trying assign a value to base class atribute (from the derived class method) causes Segmentation Fault

I have this base class:

class Netpbm {
protected:
  string magicNumber;
  int width;
  int height;
public:
  Netpbm();
  ~Netpbm();

  virtual void dump_data() = 0;
  virtual void read_file(string file_name) = 0;
  virtual void write_file(string file_name) = 0;
  virtual float * toArray() = 0;
};

and this is one of the derived classes:

class Bitmap : public Netpbm {
private:
  Matrix<int> * pixels;
public:
  Bitmap();
  ~Bitmap();

  void dump_data();
  void read_file(string file_name);
  void write_file(string file_name);

  float * toArray();

  int getWidth();
  int getHeight();
};

In the method read_file, I am trying assing values to the atributes of the class (either the ones inherited from the base class or the one declared in the derived class):

void Bitmap::read_file(string file_name) {
  fstream file;
  file.open(file_name.c_str());

  if (file.is_open()) {
    string line_one, line_two;

    if (getline(file, line_one)) {
      this->magicNumber = line_one;
    }

    if (getline(file, line_two)) {
      stringstream ss(line_two);
      string width, height;

      if(getline(ss, width, ' ')) {
        this->width = stoi(width);
      }

      if(getline(ss, height, ' ')) {
        this->height = stoi(height);
      }
    }

    pixels = new Matrix<int>(width, height);

    for(int i=0; i<height; i++ ) {
      string line_pixels;
      getline(file, line_pixels);
      for (int j=0; j<width; j++) {
        stringstream ss(line_pixels);
        string number;
        getline(ss, number, ' ');
        pixels->set(j, i, stoi(number));
      }
    }

    file.close();
    dump_data();
  }
}

the code compiles without errors or warnings, but when I try run it, I got a segmentation fault error. The backtrace command in the debugger (gdb) points the assignment of this string as the source of the error.

I also tried:

  1. comment the line this->magicNumber = line_one; in the method read_file at the subclass, and this way the method is executed until the end, when the erros happens in this scenario (leaving the class, some destructor is called, causing the isse. but i can´t figure out which one).

  2. add some getter and setter methods in the base class (for this atribute string magicNumber), but the problem persists, and now the debugger points the source the issue in this added methods.

Anyone can tell what I am doing wrong here?

UPDATE

int main(int argc, char ** argv) {
  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    return 0;
  } else {
    Bitmap bitmap;
    bitmap.read_file("letra_jota.pbm");
    Surface * view = new Surface2d("image", bitmap.getWidth(), bitmap.getHeight());
    view->loop(bitmap.toArray());
  }
  SDL_Quit();
  return 1;
}

UPDATE 2

That's the current read_file method. it runs until the end, and when try leave the method to the next instruction, i got the segmentation fault error:

void Bitmap::read_file(string file_name) {
  cout << "start read_file" << endl;
  fstream file;
  file.open(file_name.c_str());

  if (file.is_open()) {
    string line_one, line_two, line_pixels;

    if (getline(file, line_one))
      this->magicNumber = new string(line_one);

    if (getline(file, line_two)) {
      string width, height;
      stringstream ss(line_two);

      if(getline(ss, width, ' '))
        this->width = stoi(width);

      if(getline(ss, height, ' '))
        this->height = stoi(height);
    }

    pixels = new Matrix<int>(height, width);

    int line = 0;
    while(getline(file, line_pixels)) {
      string number;
      stringstream ss(line_pixels);
      for(int column=0; column<width; column++)
        if(getline(ss, number, ' ')) pixels->set(line, column, stoi(number));
      line++;
    }

    file.close();
  }

  dump_data();
  cout << "end read_file" << endl;
}

current Netpbm class:

class Netpbm {
protected:
  string * magicNumber;
  int width;
  int height;
public:
  Netpbm();
  ~Netpbm();

  virtual void dump_data() = 0;
  virtual void read_file(string file_name) = 0;
  virtual void write_file(string file_name) = 0;
  virtual float * toArray() = 0;
};

implementation:

#include "netpbm.h"

Netpbm::Netpbm() {
  cout << "constructor Netpbm" << endl;
  this->magicNumber = NULL;
}

Netpbm::~Netpbm() {
  cout << "destructor Netpbm" << endl;
  delete this->magicNumber;
}

c++

inheritance

variable-assignment

derived-class

base-class

0 Answers

Your Answer

Accepted video resources