1

I have a class which stores a vector which inherits from a generic ListAsArray class but when I try create a matrix made up of these vector classes I get a segmentation fault. A generic example of my problem is given below:

#include <iostream>
#include <vector>
using namespace std;

class ListAsArray
{
public:
    virtual void addToEnd(int i) = 0;
    virtual int operator[](int i) = 0;
};

class ListAsVector : public ListAsArray
{
public:
    void addToEnd(int i)
    {
        vec.push_back(i);
    }
    int operator[](int i)
    {
        return vec[i];
    }
private:
    vector<int> vec;
};

class FixedSizeMatrix
{
public:
    FixedSizeMatrix(int rows, int columns)
    {
        int count = 0;
        this->rows = rows;
        this->columns = columns;
        matrix = new ListAsVector[rows];
        for (int i = 0; i < rows; ++i)
        {
            for (int j = 0; j < columns; ++j)
            {
                matrix[i].addToEnd(count++);
            }
        }
    }
    ListAsArray& operator[](int i)
    {
        return matrix[i];
    }
private:
    ListAsArray* matrix;
    int rows;
    int columns;
};

int main() {
    FixedSizeMatrix m(1,2);
    cout<<m[0][0]<<endl;

    return 0;
}

The problem only occurs when I try create a matrix with more than one row. And the problem disappears when I change the type of matrix from ListAsArray* to ListAsVector* so some sort of type cast is required but I've tried almost everything and have had no success.

Because this is an assignment I am forced to have the matrix of type ListAsArray*.

Thank you in advance for any help.

Keagansed
  • 183
  • 1
  • 1
  • 13
  • 2
    You're [slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing) your object sequence.`matrix[i]` expresses as a `ListAsArray` *object*, not a reference or a pointer to some `ListAsVector` object. Thusly, only the first one lays on a proper boundary. – WhozCraig Sep 29 '16 at 08:36
  • @WhozCraig So how do I fix this? – Keagansed Sep 29 '16 at 08:39
  • @WhozCraig If I change it to ListAsArray** matrix; and change the initialization to matrix = new ListAsVector*[rows]; I get an error that says: invalid conversion from 'ListAsVector**' to 'ListAsArray**' – Keagansed Sep 29 '16 at 08:46
  • I'll write it up unless someone else does before me. – WhozCraig Sep 29 '16 at 08:47

1 Answers1

3

You're slicing your objects. When you allocate an array of ListAsVector, each object includes that std::vector<> member. However, you use ListAsArray* for accessing the sequence. Thusly, matrix[i] where i is larger than zero performs regular pointer arithmetic against the pointer type ListAsArray* (which is pretty damn small, as it has no members, but does house a vtable).

Just change the type of matrix to be ListAsVector*. (better still, use a smart pointer, or just use std::vector<ListAsVector>). The ListAsArray reference will still work for operator[], and the pointer math will once again be right with the world.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141