-4

I am quite newbie to C++. I want to create a namespace that performs compressed row storage matrix operation, but encountered an error: terminate called after throwing an instance of 'std::bad_alloc' Below is my code in a header file:

namespace matrixOperation
{
  class SparseMatrix
  {
    public:
    SparseMatrix(){
    }   
    size_t nrow, ncol, nnz;
    vector<size_t> ia, ja; 
    vector<double> a;
    ~SparseMatrix(){
    }   
  }; // end of SparseMatrix class*/

  typedef SparseMatrix CSR;
  typedef SparseMatrix csr_p;

  inline void alloc_csr(size_t nrow, size_t ncol, size_t nnz, CSR *pt)
  {
    pt = new CSR();  // this is where I think the bug occurs
    pt->nrow = nrow;
    pt->ncol = ncol;
    pt->nnz = nnz;
    pt->ia.resize(nrow+1);
    pt->ja.resize(nnz);
    pt->a.resize(nnz);
    return;
  }
} //end of namespace

Thanks for the help!

  • 1
    Not directly related, but your `alloc_csr` function would be more appropriate as a constructor of the `SparseMatrix` class. And you don't have to write `return;` at the end of a `void` function; it's implied. – Wyzard May 13 '16 at 15:51
  • To echo Nathan's comment: please show the call to `alloc_csr` too (including the values used as arguments). And since you're new to C++, you might want to check out our [list of good C++ books](http://stackoverflow.com/q/388242/1782465). – Angew is no longer proud of SO May 13 '16 at 15:51
  • Post a [MCVE] please, unless you're using some too big values for `nrow` and `ncol` there shouldn't be a problem with `SparseMatrix` (and especially not with it's default constructor). – πάντα ῥεῖ May 13 '16 at 15:54
  • Thank you all, just found the bug; the value is too large as πάντα ῥεῖ mentioned. – shidi.yan1992 May 13 '16 at 18:05

2 Answers2

2

std::bad_alloc is thrown when there is not enought memory to allocate dynamic memory, but your code looks quite OK, probably you pass too large nrow,ncol,nnz values. Maybe by accident you pass negative value which after conversion to unsigned type (like size_t) is very large.

You do have a memory leak, as pt is not a parameter which returns allocated CSR instance, to return it you need a reference:

inline void alloc_csr(size_t nrow, size_t ncol, size_t nnz, CSR *&pt)
                                                                 ^~~~~

so later you can:

matrixOperation::CSR* pcsr;
matrixOperation::alloc_csr(10, 10, 10, pcsr);
// use pcsr
delete pcsr;
marcinj
  • 48,511
  • 9
  • 79
  • 100
0

bad_alloc is thrown when the program tries to allocate more memory than the system has available. Your new CSR() call shouldn't do that, since the object only has a few fields and doesn't do any large memory allocation upon construction, but the resize calls could do it if the requested size is huge.

Wyzard
  • 33,849
  • 3
  • 67
  • 87