0

I'm trying to read input from a file, and store this input in a dynamically allocated array in my matrix class.

Every time I run this code, the input and output are both correct, but it always exits with return value 3221226356. Can anyone tell me what the problem is?

The input file is a .txt file, and it contains the number of rows, number of elements, and it looks something like this:

10 15
000000000000000
000999000009900
000999000009900
000000900009900
000090000099900
000099900000000
090000900000000
099999999900000
000090090000000
000000000000000

10 is the number of rows, and 15 is the number of elements per row.

I have to read this matrix and put this into my matArray. Every character is one Element node.

#include <bits/stdc++.h>
#include<iostream>
#include<fstream>
#include<string>
#include<cstring>


using namespace std;

class Element{
   
   private:
   char value;
   int processed;
   
   public:
   Element(){
      value = 0;
      processed = 0;
      
  }
   
   void setContent(char cellValue){ value = cellValue; }
   void setProcessed(int num1){ processed = num1; }
   char getContent(){ return value; }
   int getProcessed(){ return processed; }
};


class Matrix{

   private:
   Element* matArray;
   int rows; 
   int cols;

   public:
   Matrix(int nRows, int nCols){ 
   matArray = new Element[nRows * nCols];
   rows = nRows;
   cols = nCols;
   }

   void setInput(int r, int c, Element input){
      matArray[r * rows + c] = input;
   }

   Element getInput(int r, int c){ 
      return matArray[r * rows + c];
   }
   
};

int main(){
    
   int numRow = 0;
   int numCol = 0;
   string filename = "";
   
   string whiteSpace;
   string string1;
   
   cin >> filename;
   ifstream inFS;
   filename = filename + ".txt";
   inFS.open(filename.c_str());
   if(inFS.fail()){
      cout << "fail";
   }
   if(inFS.good()){
    cout << "good" << endl;
   }
   
   inFS >> numRow;
   inFS >> numCol;
   
   Matrix mat1(numRow, numCol);
   Element temp;
   char display;
   getline(inFS, whiteSpace);
   
//Reading the matrix from the file and inserting this information to mat1
    for(int i = 0; i < numRow; i++){
        getline(inFS, string1);
        cout << endl;
        for(int j = 0; j < numCol; j++){
           temp = mat1.getInput(i, j);
           temp.setContent(string1[j]);
           mat1.setInput(i, j, temp);      
           cout << mat1.getInput(i, j).getContent() << " ";
        }
    }
    
    cout << endl;
    
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    If you convert that number to hex you get `C0000374` which means heap corruption. Consider using a tool like AddressSanitizer or Valgrind to narrow down when it happens. – Retired Ninja Jun 16 '22 at 17:11
  • 3
    Tactical note: It looks like you're learning C++ from dodgy resources. `#include ` [is usually an unforced error](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h), but using it alongside other C++ library headers demonstrates that you don't even know what it does. – user4581301 Jun 16 '22 at 17:12
  • 2
    You are reading from the file, even when it failed to open it. – mch Jun 16 '22 at 17:14
  • 2
    If opening the file fails, you simply continue? Not a good idea. All it takes would be returning something other than 0 to avoid any issues later on, since the logic is part of the `main` function... – fabian Jun 16 '22 at 17:15
  • 2
    `#include ` -- 1) Get rid of this header. 2) Use `#include ` 3) Change `Element* matArray;` to `std::vector matArray;`. 4) Use `Matrix(int nRows, int nCols) : matArray(nRows * nCols), rows(nRows), cols(nCols) {}` 5) Use `at()` to access the items in `matArray` instead of `[]`. If the file read *is* successful, then that should point you to where the problem is. – PaulMcKenzie Jun 16 '22 at 17:17
  • 1
    Side note: I see `new` in the code, but no `delete`. Memory is being leaked. – user4581301 Jun 16 '22 at 17:18
  • Note: you could implement read&write access in one go by simply returning a reference: `struct Index { size_t row; size_t column; }; Element& operator[](Index const& index) { return matArray[index.row*cols+ index.column]; } ... mat1[{i, j}].setContent(string1[j]);` which would allow you to void having to do 2 function calls to modify an element. You do not need the `Index` type btw, if you implement the access via a function other than the overloaded `[]` operator. – fabian Jun 16 '22 at 17:27

1 Answers1

3

Your index calculations in setInput() and getInput() are wrong, causing you to access matArray's elements out of bounds, which is undefined behavior. You need to multiply the r parameter by cols (the number of elements per row) instead of by rows (the number of rows), eg:

void setInput(int r, int c, Element input){
    matArray[(r * cols) + c] = input;
}

Element getInput(int r, int c){ 
    return matArray[(r * cols) + c];
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770