-2

I have the following function in c++

void LocatePulseEdges(int points, double* signal_x, double* signal_y, double* derivative, double threshold, double* left_edge, double* right_edge){
    for (int i=0; i<points; i++){
        if(signal_y[i]<threshold){
            left_edge.push_back(signal_x[i]);
        }
    }
}

When I compile it, I get the error

In function ‘void LocatePulseEdges(int, double*, double*, double*, double, double*, double*)’:
error: request for member ‘push_back’ in ‘left_edge’, which is of non-class type ‘double*’

Since I am a novice in c++ and I obviously, trying to learn about pointers and how to use them, I can't understand why I can't use push_back.

I also tried to use (*left_edge) or (*signal_y[i]) but as expected it wasn't proper...

Any idea or help would be more than welcome!

EDIT

I modified the code as follows

void LocatePulseEdges(int points, double* signal_x, double* signal_y, double* derivative, double threshold, vector<double> left_edge, vector<double> right_edge){
    for (int i=0; i<points; i++){
        if(signal_y[i]<threshold){
            left_edge.push_back(signal_x[i]);
        }
    }
}

Then in my code I call the function like this

void Analyze(unsigned int first_run, unsigned int last_run, unsigned int last_segment){
    double* x          = new double[points];           // SIZE limited only by OS/Hardware
    double* y          = new double[points];
    double* derivative = new double[points];
    std::vector<double> left_edge;
    std::vector<double> right_edge;

    Function_to_Fill_X_and_Y_and_derivative();

    LocatePulseEdges(points, x, y, derivative, -0.5*RMS, left_edge, right_edge);


}

Although I get no compilation errors, the program crashes as soon as the function is called.

Thanos
  • 594
  • 2
  • 7
  • 28
  • `double*` is build-in type, it doesn't have any members. You might want sth like `left_edge[any_index] = signal_x[i];`. – songyuanyao Jun 24 '16 at 07:17
  • 1
    `left_edge` is not a container. – Retired Ninja Jun 24 '16 at 07:17
  • @songyuanyao : Thanks for your comment! The thing is that `signal_x.Size()` is quite huge (i.e. ~1e7) therefore I thought of using `push_back` in order to save some space in memory. – Thanos Jun 24 '16 at 07:19
  • use std::vector instead of pointers/array if you want to have access to push_back. – Falla Coulibaly Jun 24 '16 at 07:20
  • @RetiredNinja Thanks for your comment! Since I am a novice, I don't really get what you are saying... `left_edge` is a pointer and as far as I can understand it can be related to an array, isn't that right? Off course it is evident that I don't exactly know how... – Thanos Jun 24 '16 at 07:21
  • Where do you know about `push_back`? – songyuanyao Jun 24 '16 at 07:22
  • @songyuanyao : I read about it here http://www.cplusplus.com/reference/vector/vector/push_back/ – Thanos Jun 24 '16 at 07:24
  • @Thanos This `push_back` is a member function of `std::vector`, so you should use it with `std::vector`, not a `double*`. – songyuanyao Jun 24 '16 at 07:26
  • @songyuanyao I see... So what should I do if I want to fill `double* left_edge` (which is supposed to be an array) using a push_back-like technique? – Thanos Jun 24 '16 at 07:28
  • @Thanos Baltasarq has given the steps in his answer about how to do it manually. Basically it's not a good idea. – songyuanyao Jun 24 '16 at 07:32
  • You might want to grab a [good C++ book](http://stackoverflow.com/q/388242/1782465) to get a firm grip on the basic principles. – Angew is no longer proud of SO Jun 24 '16 at 07:51
  • You have to pass the vectors as references: std::vector &left_edge;. Look, it is difficult to help you if you don't know even the basics. Follow the advice given by others and try a good book before. – Baltasarq Jun 24 '16 at 13:02

2 Answers2

3

The problem here is that you are using left_edge as if it were a container such as a list or vector, and it is just a double *, i.e., a pointer to a double, or maybe (probably this is from where it comes the confusion) an array of double's. Even if it is the latter, you cannot add elements that way, arrays are fixed in length. Finally, you have to "remember" the length of each array, since C++ won't do that for you.

The way to expand an array is to:

  1. allocate more space with new,
  2. copy the values from the old space,
  3. and add the new values to the new space.

So, for example, say you create your array with one element x:

double * left_edge;
int length = 1;
left_edge = new double[ length ];
left_edge[ 0 ] = x;

Then you need more space, a new element x:

double * new_space = new double[ length + 1 ];

for (int i = 0; i < length; ++i) {
    new_space[ i ] = left_edge[ i ];
}

new_space[ length ] = x;
++length;
delete[] left_edge;
left_edge = new_space;

Which is what exactly std::vector<double> would do for you calling push_back(). The only thing is that you have to define it from the beginning that way, and pass it to the function LocatePulseEdges as a reference.

std::vector<double> left_edge;

If you are going to just add at the end, then std::vector<> is the answer. If you are going to insert in the middle, then you should choose std::list<> instead.

Hope this helps.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
  • Thank you for your answer! I tried to defined it as you described, but my program crushes, although I get no compilation error! Please check my edited question. – Thanos Jun 24 '16 at 07:44
1

push_back is a method of the std::vector class. You should consider to use std::vector<double> instead. If you use a double*, you have to do this way :

left_egde[index] = signal_x[i] ;
index++ ;

with index properly initialized. This is less safe than std::vector because you need to allocate enough memory when declaring

double *left_edge = new double[whatever_lenght] ;
Irminsul
  • 171
  • 9