I wrote a very simple vector class to call level 1 BLAS through MKL,

#include<mkl.h>
#include<stdexcept>

#ifndef _x_matrix
#define _x_matrix
class xVec{
private:
  double *v;
  int    n;
public:
  xVec():n(0),v(0){}
  xVec(int a):n(a),v(new double[n]){}
  xVec(int a, double c){
    n=a;
    v=new double[n];
    for(int i=0; i<n; ++i) v[i]=c;
  }

  ~xVec(){if(v) delete[]v;}

  double &operator()(int i){
    if(i<n) return v[i];
    else throw runtime_error("Out of boundary.");
  }

  double asum(int incx=1){
    // return sum v by incx
    return dasum(&n, v, &incx);
  }
};

Then,

const int n(100);
  xVec x(n,10););
  cout<<x.asum()<<endl;

The results are unstable, sometimes it's right, some time it give error like,

terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc

or,
segment fault etc.

What's wrong there?

Edited 6 Years Ago by qtl: n/a

I think you may be messing with undefined behavior with your initializers in your 1-argument version of your constructor.

Both of these constructors should have similar construction:

xVec(int a):n(a),v(new double[n]){}  //potential undefined behavior!!
  xVec(int a, double c){
    n=a;
    v=new double[n];
    for(int i=0; i<n; ++i) v[i]=c;
  }

It's generally not a good idea to reference member variables from the initialization statement(s) because there is no guarantee that they exist yet. However, they are guaranteed to exist by the time you reach the body of the constructor. This gives you 2 options:

//option 1
constructor2(int a):m_int(a),m_pDbl(new double[a]){} //notice the use of 'a' instead of 'm_int'...
//option 2, the option I prefer
constructor2(int a):m_int(a){
  m_pDbl = new double[m_int];  //note that allocation is in the body
}

A third option, that can reduce the code required would be:

constructor2(int a, double c = 0.0): m_int(a) {
  m_pDbl = new double[m_int];
  for(int i=0; i < m_int; ++i) m_pDbl[i]=c;
}

Some people don't like this version though because it uses default values for arguments/parameters. But, it allows you to call it as either xVec(int) or as xVec(int, double). I wouldn't recommend it though if you're not familiar with the concept of default arguments and their syntax.

Edited 6 Years Ago by Fbody: n/a

Not to be picky here, and it has very little to do with the question you're actually asking, but don't get in a habit of meaningless variable and function names (e.g., v, n, xVec, asum, etc.). In fact, the opposite is a more industry accepted approach. I made the mistake during my schooling of, in an attempt to get the program working, not worry about what I called my variables because I knew what they meant and that's all that mattered. However, when I started working on larger more independent projects (projects that might actually be picked up by another programmer one day or that has over 500 lines of code) I found myself continuing my old habits without realizing it sometimes.

Now, while you're learning and in school, start doing the opposite - over describe your variables. It's ok for your professor to jot down meaningless variables in class, as they're merely for demonstration. As for your programs, attempt to be as descriptive as possible with both your functions and variable names.

Some examples from the software I debug daily:

FfsApportionmentDocumentAmendmentDataEntryCritic
FfsAssetDetailAcctgLineIdentityPtr

GetRuleCustomerAccountTreatment()
GetItemLineOriginalAmount()
AddDocumentTypeDefinedAccountingLineCodeColumns()

Just some food for thought.

Edited 6 Years Ago by Duki: n/a

to Fbody: I adopted you option 2, i.e. using a to initialize. The problem is gone. many thanks.

to Duki: Thanks also for your suggestion. My daily job is actually not that complicated. I use basic vector and matrix for some linear algebra calculation. Vec is quite meaningful to indicate a vector. Complicated names might be for a real object not this class. dasum is a BLAS sub with some conventions. I can remember them as I used them often.

Edited 6 Years Ago by qtl: n/a

This question has already been answered. Start a new discussion instead.