Search code examples
c++arrayspointerspush-back

How to use push_back with double* pointer


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.


Solution

  • 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.