returning STL object from container class method

I am writing a sparse matrix container class using map<row, map<col, val> > as my data. In my matrix-vector multiplication method I want to return an STL vector. My code compiles, but at run-time I get "terminate called without an active exception". I have also tried allocation of the return object on the heap with "new", but this gives an assignment error. What is going badly in my operation* method?

Thanks for the help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
template <class T> class Matrix
{
public:
    typedef map<size_t, map<size_t , T> > matrix_t;
    typedef typename matrix_t::iterator matrix_iter;
    typedef map<size_t, T> map_t;
    typedef typename map_t::iterator map_iter;

    matrix_t mat;
    size_t m;
    size_t n;

    Matrix(){}
    Matrix(size_t i, size_t j){ m=i; n=j; }

    //inline
    //~Matrix(){ delete[] mat; }

    inline
    T& operator()(size_t i, size_t j)
    {
        if(i>=m || j>=n) throw;
        return mat[i][j];
    }
    inline
    T operator()(size_t i, size_t j) const
    {
        if(i>=m || j>=n) throw;
        return mat[i][j];
    }

    vector<T> operator*(const vector<T>& x)
    {
        //if(mat.n != x.size()) throw;

        vector<T> y;
        T sum;

        matrix_iter ii;
        map_iter jj;

        ii=mat.begin();
        while( ii!=mat.end() )
        {
            jj=(*ii).second.begin();
            sum=0;
            while( jj!=(*ii).second.end() )
            {
                sum += (*jj).second * x[(*jj).first];
                jj++;
            }
            y[(*ii).first]=sum;
            ii++;
        }
        return y;
    }

    void printMat()
    {
        matrix_iter ii;
        map_iter jj;
        for(ii=mat.begin(); ii!=mat.end(); ii++)
        {
            for( jj=(*ii).second.begin(); jj!=(*ii).second.end(); jj++)
            {
                cout << (*ii).first << ' ';
                cout << (*jj).first << ' ';
                cout << (*jj).second << endl;
            }
        } cout << endl;
    }
};


int init(Matrix<long double> &A)
{
    ifstream fin("matin.txt");
    int n,length,i,j;
    if(fin.is_open())
    {
        fin >> n;
	fin >> length;
        int k=0;
        while(k<length){ fin >> i >> j; fin >> A(i-1,j-1); k++; }
        fin.close();
    }
    else return 0;
    return n;
}

int main ()
{
    Matrix<long double> A(3,3);
    vector<long double> x, y;
    long double sum;
    int n,k=0;
    clock_t t0,tf;
    cout.precision(17);
    n=init(A);
    for(int i=0;i<3;i++){ x[i]=1; }

    A.printMat();
    cout << A.m << ' ' << A.n << '\n';
    
    y=A*x;
    
    for(int i=0;i<3;i++){ cout << y[i] << ' '; }

    return 0;
}
Last edited on
I already answered this on the other general C++ forum. You need to read the documentation on std::vector. You are not using vectors correctly. You are trying to create empty vectors and then fill them with operator[]. This will cause undefined behavior. You have to fill the vector using the insert, assign, or push_back member functions. You can only use operator[] to access existing elements of the container.
vector<long double> x(1000,1), for instance, is okay right? Then I will be able to use [].

Thanks
Last edited on
vector<long double> x(1000,1), for instance, is okay right? Then I will be able to use [].

Yes, something like that. You have to figure out how big it needs to be and pick an appropriate value but you have the idea.
Topic archived. No new replies allowed.