1

I am facing an issue with a 2D array of pointers. It compiles with no errors, however when I try to run the file, all I get is a single line saying I have a segmentation fault.

My header file:

#ifndef __TWODARRAY_H__
#define __TWODARRAY_H__

template <typename T>
class TwoDArray {
  private:
    T** theArray;
    int numRows;
    int numCols;
    T defSpace;

  public:
    TwoDArray<T> (int r, int c, T def);
    ~TwoDArray<T>();
    void insert(int r, int c, T value);
    T access(int r, int c);
    void remove(int r, int c);
    void print();
    int getNumRows();
    int getNumCols();
};
#endif

My Methods:

#include "TwoDArray.h"
#include <iostream>
#include <assert.h>
#include <string>

//initializes the 2D Array
template <typename T>
TwoDArray<T>::TwoDArray(int r, int c, T def) {
  assert(r > 0 && c > 0);
  numRows = r;
  numCols = c;
  defSpace = def;
  theArray = new T*[r];
  for(int i=0; i<r; i++) {
    theArray[i] = new T[c];
  }
  //sets all values to the default
  for(int i=0; i<r; i++) {
    for(int j=0; j<c; j++) {
    theArray[i][j] = defSpace;
    }
  }
}

//deletes the 2D Array
template<typename T>
TwoDArray<T>::~TwoDArray() {
  for(int i=0; i<numRows; i++) {
    delete[] theArray[i];
  }
  delete[] theArray;
}

//inserts value v at row r and column c
template<typename T>
void TwoDArray<T>::insert(int r, int c, T value) {
  assert(r < numRows && c < numCols);
  assert(value != defSpace);
  theArray[r][c] = value;
}

//get value at row r, column c
template<typename T>
T TwoDArray<T>::access(int r, int c) {
  assert(r < numRows && c < numCols);
  T result = theArray[r][c];
  return result;
}

//set value at row r and column c back to default
template<typename T>
void TwoDArray<T>::remove(int r, int c) {
  assert(r < numRows && c < numCols);
  assert(theArray[r][c] != defSpace);
  theArray[r][c] = defSpace;
}

//print the 2D Array
template<typename T>
void TwoDArray<T>::print() {
  for(int i=0; i<numRows; i++) {
    for(int j=0;j<numCols; i++) {
      std::cout << theArray[i][j];
      std::cout << " ";
    }
    std::cout << std::endl;
  }
}

//gets number of rows for test
template<typename T>
int TwoDArray<T>::getNumRows() {
  return numRows;
}

//gets number of columns for test
template<typename T>
int TwoDArray<T>::getNumCols() {
  return numCols;
}

template class TwoDArray<int>;
template class TwoDArray<std::string>;

And my main:

#include <iostream>
#include <string>
#include "TwoDArray.h"

using std::cout;
using std::endl;

int main() {
  TwoDArray<int>* i = new TwoDArray<int>(5, 5, 0);

  TwoDArray<std::string>* s = new TwoDArray<std::string>(5, 5, "o");

  i->insert(1, 1, 1);
  i->insert(1, 3, 1);
  i->insert(3, 2, 8);
  i->insert(2, 0, 3);
  i->insert(2, 4, 3);
  i->insert(3, 2, 8);

  i->print();


  s->insert(0, 2, "North");
  s->insert(4, 2, "South");
  s->insert(2, 4, "East");
  s->insert(2, 0, "West");

  s->print();

  return 0;
}

Any ideas why I'm getting a segmentation fault?

1
  • You get specific line? What environment you are on? Did you try debugging ? Commented Oct 25, 2012 at 19:28

1 Answer 1

5

This is a mistake:

template<typename T>
void TwoDArray<T>::print() {
  for(int i=0; i<numRows; i++) {
    for(int j=0;j<numCols; i++) {   // should be j++, not i++
      std::cout << theArray[i][j];
      std::cout << " ";
    }
    std::cout << std::endl;
  }
}

as i is being incremented in both the outer and inner for and will eventually lead to i equalling numRows and going one past the end of the array, which is undefined behaviour and a possible cause of the segmentation fault.

As there is a dynamically allocated member in TwoDArray you need to prevent copying of instances of TwoDArray or implement the assignment operator and copy constructor (see What is The Rule of Three?).

If this is not a learning exercise you could use a vector<vector<T>> instead.

Also, as the dimensions of the array are compile time constants it is possible to make them template parameters also and avoid dynamic memory completely:

template <typename TType, int TRows, int TCols>
class TwoDArray {
  private:
    TType theArray[TRows][TCols];
    TType defSpace;
    ....

TwoDArray<int, 5, 5> i(0);

see http://ideone.com/dEfZn5 for full demo.

Sign up to request clarification or add additional context in comments.

3 Comments

@JohnnyMopp Seems like a good time to learn to use a debugger :)
This helped me part of the way, but now it's has a segmentation fault with the string array, but thank you!
@RazGarth, I can't see what the problem is and it seems fine: ideone.com/EdrY7J

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.