title: What is causing heap corruption and extraneous values in my code?
body: <p>I'm writing code for a project in my class, and it is producing incredibly unusual results. Row and column values end up with random numbers in the millions and it eventually throws exceptions and I can't understand why.</p>
  
  <pre><code>#include &lt;iostream&gt;
  using namespace std;
  
  class SparseRow {
  protected:
      int row;
      int col;
      int value;
  public:
      SparseRow();
      SparseRow(int inRow, int inCol, int inVal);
      SparseRow(const SparseRow&amp; newRow);
      SparseRow&amp; operator=(const SparseRow&amp; newRow);
      ~SparseRow();
      void display();
      int getRow();
      int getCol();
      int getValue();
      void setRow(int inRow);
      void setCol(int inCol);
      void setValue(int inVal);
  };
  
  class SparseMatrix {
  protected:
      int noRows;
      int noCols;
      int commonValue;
      int noSparseValues;
      SparseRow *myMatrix;
      void setNoSparseValues(int noSV);
  public:
      SparseMatrix();
      SparseMatrix(int rows, int cols, int cv, int noSV);
      SparseMatrix(const SparseMatrix&amp; matrix);
      SparseMatrix&amp; operator=(const SparseMatrix&amp; matrix);
      ~SparseMatrix();
      void readMatrix();
      SparseMatrix* transpose();
      SparseMatrix* multiply(SparseMatrix&amp; M);
      SparseMatrix* add(SparseMatrix&amp; M);
      void display();
      void displayMatrix();
      int getNoRows();
      int getNoCols();
      int getCommonValue();
      int getNoSparseValues();
      int getValue(int row, int col);
      void setValue(int row, int col, int val);
  };
  
  SparseRow::SparseRow() {
      row = -1;
      col = -1;
      value = 0;
  }
  
  SparseRow::SparseRow(int inRow, int inCol, int inVal) {
      row = inRow;
      col = inCol;
      value = inVal;
  }
  
  SparseRow::SparseRow(const SparseRow&amp; newRow) {
      row = newRow.row;
      col = newRow.col;
      value = newRow.value;
  }
  
  SparseRow&amp; SparseRow::operator=(const SparseRow&amp; newRow) {
      if (this != &amp;newRow) {
          row = newRow.row;
          col = newRow.col;
          value = newRow.value;
      }
      return *this;
  }
  
  SparseRow::~SparseRow() {
      cout &lt;&lt; "Deleting SparseRow with values: " &lt;&lt; endl;
      display();
  }
  
  void SparseRow::display() {
      cout &lt;&lt; "Row: " &lt;&lt; row &lt;&lt; ", Column: " &lt;&lt; col &lt;&lt; ", Value: " &lt;&lt; value &lt;&lt; endl;
  
  }
  
  int SparseRow::getRow() {
      return row;
  }
  
  int SparseRow::getCol() {
      return col;
  }
  
  int SparseRow::getValue() {
      return value;
  }
  
  void SparseRow::setRow(int inRow) {
      row = inRow;
  }
  
  void SparseRow::setCol(int inCol) {
      col = inCol;
  }
  
  void SparseRow::setValue(int inVal) {
      value = inVal;
  }
  
  SparseMatrix::SparseMatrix() {
      noRows = 0;
      noCols = 0;
      commonValue = 0;
      noSparseValues = 0;
  }
  
  SparseMatrix::SparseMatrix(int rows, int cols, int cv, int noSV) {
      noRows = rows;
      noCols = cols;
      commonValue = cv;
      noSparseValues = noSV;
      myMatrix = new SparseRow[rows * cols];
  }
  
  SparseMatrix::SparseMatrix(const SparseMatrix&amp; matrix) {
      noRows = matrix.noRows;
      noCols = matrix.noCols;
      commonValue = matrix.commonValue;
      noSparseValues = matrix.noSparseValues;
      myMatrix = matrix.myMatrix;
  }
  
  SparseMatrix&amp; SparseMatrix::operator=(const SparseMatrix&amp; matrix) {
      if (this != &amp;matrix) {
          delete[] myMatrix;
  
          noRows = matrix.noRows;
          noCols = matrix.noCols;
          commonValue = matrix.commonValue;
          noSparseValues = matrix.noSparseValues;
          myMatrix = matrix.myMatrix;
      }
      return *this;
  }
  
  SparseMatrix::~SparseMatrix() {
      cout &lt;&lt; "Deleting SparseMatrix with values: " &lt;&lt; endl;
      display();
  
      delete[] myMatrix;
  }
  
  void SparseMatrix::readMatrix() {
      int count = 0;
      int val;
  
      for (int i = 0; i &lt; noRows; i++) {
          for (int j = 0; j &lt; noCols; j++) {
              cin &gt;&gt; val;
              if (val != commonValue) {
                  myMatrix[count].setRow(i);
                  myMatrix[count].setCol(j);
                  myMatrix[count].setValue(val);
                  // Why does C++ prevent me from calling a constructor on objects in an array? It doesn't make sense.
                  count++;
              }
          }
      }
  
      if (count != noSparseValues) {
          cout &lt;&lt; "ERROR: Incorrect number of sparse values! Changing to correct number." &lt;&lt; endl;
          noSparseValues = count;
      }
  }
  
  SparseMatrix* SparseMatrix::transpose() {
      SparseMatrix *newMatrix = new SparseMatrix(noCols, noRows, commonValue, noSparseValues);
  
      for (int i = 0; i &lt; noSparseValues; i++) {
          newMatrix-&gt;setValue(myMatrix[i].getCol(), myMatrix[i].getRow(), myMatrix[i].getValue());
      }
  
      return newMatrix;
  }
  
  SparseMatrix* SparseMatrix::multiply(SparseMatrix&amp; M) {
      if (noCols != M.getNoRows()) {
          cout &lt;&lt; "ERROR: Matrices cannot be multiplied!" &lt;&lt; endl;
          return NULL;
      }
  
      SparseMatrix *newMatrix = new SparseMatrix(noRows, M.getNoCols(), commonValue, noRows * M.getNoCols());
      // Why does C++ prevent me from creating an array to store this information? It doesn't make sense.
  
      int SVCount = 0;
      for (int i = 0; i &lt; noRows; i++) {
          for (int j = 0; j &lt; M.getNoCols(); j++) {
              int sum = 0;
              for (int k = 0; k &lt; noCols; k++) {
                  sum += getValue(i, k) * M.getValue(k, j);
              }
              if (sum != newMatrix-&gt;getCommonValue()) {
                  SVCount++;
              }
              newMatrix-&gt;setValue(i, j, sum);
          }
      }
      newMatrix-&gt;setNoSparseValues(SVCount);
  
      return newMatrix;
  }
  
  SparseMatrix* SparseMatrix::add(SparseMatrix&amp; M) {
      if (noRows != M.getNoRows() || noCols != M.getNoCols()) {
          cout &lt;&lt; "ERROR: Matrices cannot be added!" &lt;&lt; endl;
          return NULL;
      }
  
      SparseMatrix *newMatrix = new SparseMatrix(noRows, noCols, commonValue + M.getCommonValue(), noRows * noCols);
  
      int SVCount = 0;
      for (int i = 0; i &lt; noRows; i++) {
          for (int j = 0; j &lt; noCols; j++) {
              int sum = getValue(i, j) + M.getValue(i, j);
              if (sum != newMatrix-&gt;getCommonValue()) {
                  SVCount++;
              }
              newMatrix-&gt;setValue(i, j, sum);
          }
      }
  
      newMatrix-&gt;setNoSparseValues(SVCount);
  
      return newMatrix;
  }
  
  void SparseMatrix::display() {
      for (int i = 0; i &lt; noSparseValues; i++) {
          myMatrix[i].display();
      }
  }
  
  void SparseMatrix::displayMatrix() {
      for (int i = 0; i &lt; noRows; i++) {
          for (int j = 0; j &lt; noCols; j++) {
              cout &lt;&lt; getValue(i, j) &lt;&lt; " ";
          }
          cout &lt;&lt; endl;
      }
  }
  
  int SparseMatrix::getNoRows() {
      return noRows;
  }
  
  int SparseMatrix::getNoCols() {
      return noCols;
  }
  
  int SparseMatrix::getCommonValue() {
      return commonValue;
  }
  
  int SparseMatrix::getNoSparseValues() {
      return noSparseValues;
  }
  
  void SparseMatrix::setNoSparseValues(int noSV) {
      noSparseValues = noSV;
  }
  
  int SparseMatrix::getValue(int row, int col) {
      for (int i = 0; i &lt; noSparseValues; i++) {
          if (myMatrix[i].getRow() == row &amp;&amp; myMatrix[i].getCol() == col) {
              return myMatrix[i].getValue();
          }
      }
      return commonValue;
  }
  
  void SparseMatrix::setValue(int row, int col, int val) {
      bool replacingSparse = (getValue(row, col) != commonValue);
      bool replacingWithSparse = (val != commonValue);
  
      int index = -1;
  
      if (replacingSparse) {
          for (int i = 0; i &lt; noSparseValues; i++) {
              if (myMatrix[i].getRow() == row &amp;&amp; myMatrix[i].getCol() == col) {
                  index = i;
                  break;
              }
          }
          if (replacingWithSparse) {
              myMatrix[index].setValue(val);
          }
          else {
              for (int i = index; i &lt; noSparseValues; i++) {
                  myMatrix[i] = myMatrix[i + 1];
              }
              noSparseValues--;
          }
      }
      else {
          if (replacingWithSparse) {
              for (int i = 0; i &lt; noSparseValues; i++) {
                  if (myMatrix[i].getRow() &gt; row || (myMatrix[i].getRow() &gt;= row &amp;&amp; myMatrix[i].getCol() &gt; col)) {
                      index = i;
                      break;
                  }
              }
              for (int i = noSparseValues; i &gt; index; i--) {
                  myMatrix[i] = myMatrix[i - 1];
              }
              myMatrix[index].setRow(row);
              myMatrix[index].setCol(col);
              myMatrix[index].setValue(val);
              noSparseValues++;
          }
      }
  }
  
  int main() {
      int n, m, cv, noNSV;
      SparseMatrix* temp;
  
      cin &gt;&gt; n &gt;&gt; m &gt;&gt; cv &gt;&gt; noNSV;
      SparseMatrix* firstOne = new SparseMatrix(n, m, cv, noNSV);
      firstOne-&gt;readMatrix();
  
      cin &gt;&gt; n &gt;&gt; m &gt;&gt; cv &gt;&gt; noNSV;
      SparseMatrix* secondOne = new SparseMatrix(n, m, cv, noNSV);
      secondOne-&gt;readMatrix();
  
      cout &lt;&lt; "First one in sparse matrix format" &lt;&lt; endl;
      firstOne-&gt;display();
  
      cout &lt;&lt; "First one in normal matrix format" &lt;&lt; endl;
      firstOne-&gt;displayMatrix();
  
      cout &lt;&lt; "Second one in sparse matrix format" &lt;&lt; endl;
      secondOne-&gt;display();
  
      cout &lt;&lt; "Second one in normal matrix format" &lt;&lt; endl;
      secondOne-&gt;displayMatrix();
  
      cout &lt;&lt; "After Transpose first one in normal format" &lt;&lt; endl;
      temp = firstOne-&gt;transpose();
      temp-&gt;displayMatrix();
  
      cout &lt;&lt; "After Transpose second one in normal format" &lt;&lt; endl;
      temp = secondOne-&gt;transpose();
      temp-&gt;displayMatrix();
  
      cout &lt;&lt; "Multiplication of matrices in sparse matrix form:" &lt;&lt; endl;
      temp = secondOne-&gt;multiply(*firstOne);
      temp-&gt;display();
  
      cout &lt;&lt; "Addition of matrices in sparse matrix form:" &lt;&lt; endl;
      temp = secondOne-&gt;add(*firstOne);
      temp-&gt;display();
  }
  </code></pre>
  
  <p><strong>Input:</strong></p>
  
  <pre><code>3 3 0 3
  2 2 2
  0 0 0
  0 0 0
  
  3 3 0 3
  2 2 2
  0 0 0
  0 0 0
  </code></pre>
  
  <p><strong>Expected output:</strong> (not formatted exactly the same, but the numbers should be identical)</p>
  
  <pre><code>First one in sparse matrix format
  0, 0, 2
  0, 1, 2
  0, 2, 2
  First one in normal matrix format
  2     2     2
  0     0     0
  0     0     0
  Second one in sparse matrix format
  0, 0, 2
  0, 1, 2
  0, 2, 2
  Second one in normal matrix format
  2     2     2
  0     0     0
  0     0     0
  After Transpose first one
  2     0     0
  2     0     0
  2     0     0
  After Transpose second one
  2     0     0
  2     0     0
  2     0     0
  Multiplication of matrices in sparse matrix form:
  0, 0, 4
  0, 1, 4
  0, 2, 4
  Addition of matrices in sparse matrix form:
  0, 0, 4
  0, 1, 4
  0, 2, 4
  </code></pre>
  
  <p><strong>Actual output:</strong></p>
  
  <pre><code>First one in sparse matrix format
  Row: 0, Column: 0, Value: 2
  Row: 0, Column: 1, Value: 2
  Row: 0, Column: 2, Value: 2
  First one in normal matrix format
  2 2 2
  0 0 0
  0 0 0
  Second one in sparse matrix format
  Row: 0, Column: 0, Value: 2
  Row: 0, Column: 1, Value: 2
  Row: 0, Column: 2, Value: 2
  Second one in normal matrix format
  2 2 2
  0 0 0
  0 0 0
  After Transpose first one in normal format
  0 0 0
  2 0 0
  2 0 0
  After Transpose second one in normal format
  0 0 0
  2 0 0
  2 0 0
  Multiplication of matrices in sparse matrix form:
  Row: 0, Column: 1, Value: 4
  Row: 0, Column: 2, Value: 4
  Row: 369, Column: -33686019, Value: 9
  Addition of matrices in sparse matrix form:
  (Exceptions thrown here, line 222 in code)
  </code></pre>
  
  <p><strong>Exceptions thrown:</strong></p>
  
  <pre><code>Project1.exe has triggered a breakpoint.
  
  Unhandled exception at 0x777E8499 (ntdll.dll) in Project1.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77825890).
  </code></pre>