Why is this vector copying its first element?

user3303504

I'm relatively new to vectors and this problem has left me baffled.

I have 2 vectors of data which contain a breakdown of a previously analysed graph (locations of peaks, and inflexion points). What the function below is supposed to do is find the inflexion points either side of the mean locations, and store them in "left" and "right" vectors. The left vector gets the correct data, however no matter what I do the right vector collects the first point, and then copies that point every time I try to add a new one.

Code:

void pairs(std::vector<int> &means, std::vector<int> &inflexions, std::vector<int> &inflexLeft, std::vector<int> &inflexRight)
{
    //////////////
    //INITIALISE//
    //////////////

    if((means.size() <= 0) || inflexions.size() <= 0)               // If nothing to do
    {
        means.clear();                                              // Leave nothing to chance...
        inflexions.clear();
        return;                                                     // And do nothing =)
    }

    inflexLeft.clear();
    inflexRight.clear();
    inflexLeft.reserve(means.size());
    inflexRight.reserve(means.size());
    std::vector<int>::iterator itI = inflexions.begin();
    std::vector<int>::iterator inflexStart = itI;
    std::vector<int>::iterator endI = inflexions.end();
    std::vector<int>::iterator itM = means.begin();
    std::vector<int>::iterator endM = means.end();

    /////////////////
    //COLLECT PAIRS//
    /////////////////

    for(; (itM != endM) && (itI != endI); itM++, itI++)             // For all the elements in the "means" list
    {
        for(; itI != endI; itI++)
        {
            std::cout<<*itI<<", \t";

            if((*itI) > (*itM))                                     // If we've gone past a mean value...
            {
                if(itI == inflexStart)                              // And this isn't the beginning
                {inflexLeft.push_back(-1);}
                else
                {inflexLeft.push_back(*(itI-1));}                   // Then store the previous inflexion point as LHS inflex for this mean

                inflexRight.push_back(*itI);                        // And store the current inflexion point as the RHS variant
                break;
            }
            else if((itI == endI-1) && (inflexStart != endI-1))     // If we're at the end and have nowhere else to go
            {
                inflexLeft.push_back(*(itI-1));                     // Set the LHS inflex point as the one prior to this...
                inflexRight.push_back(-1);                          // And set the RHS to NULL
                break;
            }
        }
        std::cout<<std::endl;
    }
}

Example output:

1,  2,  3,  4,  11,     
13,     20,     22,     23,     25,     29,     32,     35,     36,     42,     
44,     47,     53,     54,     58,     

Output: (inflexLeft on left, inflexRight on right)
4,      11,     
36,     11,     
54,     11,

Every new line in the example above is where a mean occurs and the inflexion points should be stored appropriately. The left hand column of the output is the left inflexion points, and the right should be showing something similar (e.g. 6, 50, 73, ... etc).

I am using QT creator 2.6.1, based on QT 4.8.3 using minGW, on Windows 7 64 bit. Header files included:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <cmath>
#include <stdexcept>

Thanks in advance for any help.

//////////////////EDIT/////////////////

I've re-doubled my efforts with the debugger. I've used the code below to view the memory address of the point I'm pointing at just before I try to push it back:

std::cout << &*itI << ", \t" << *itI << ", \t";

From that I've confirmed that the iterator itself isn't magically pointing somewhere else and is indeed iterating. This means that the line of code the problem lies with is:

inflexRight.push_back(*itI);                        // And store the current inflexion point as the RHS variant

I have already tried putting this line above the LHS push_back operation etc, and the result is the same. I've even tried copying the data into a temporary value before handing it over to inflexRight.push_back with no change in results.

Code to output the final result is in the main function:

for(; itLeft != itEnd; itLeft++, itRight++)
{
    std::cout << *itLeft << ", \t" << *itRight << ", \t" << std::endl;
}
std::cout << std::endl;
Gall

So I have run a simplified version with your exact function pairs (the means values are set to output something similar to what you should have I think)

int main() {
    std::vector<int> inflex = {
            1,  2,  3,  4,  11,
            13, 20, 22, 23, 25, 29, 32, 35, 36, 42,
            44, 47, 53, 54, 58
        },
        means = { 10, 40, 55 },
        left,
        right;

    pairs(means, inflex, left, right);

    std::vector<int>::const_iterator itLeft(left.begin()),
        itRight(right.begin()),
        itEnd(left.end());
    for(; itLeft != itEnd; itLeft++, itRight++)
    {
        std::cout << *itLeft << ", \t" << *itRight << ", \t" << std::endl;
    }
    std::cout << std::endl;

    return 0;
}

and I got this

1,  2,  3,  4,  11,     
13,     20,     22,     23,     25,     29,     32,     35,     36,     42,     
44,     47,     53,     54,     58,     
// Output: (inflexLeft on left, inflexRight on right)
4,      11,     
36,     42,     
54,     58,

So I don't think the problem comes from the part of the code you're showing, your pairs function should be correct.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Clojure: Increment every item of a list/vector by its first element

Why it's not a good idea to hold an instance with out first copying it via its copy constructor?

How to derive the size of vector inside a function? (the vector is passed by a pointer to its first element)

Why do I get a first empty element in a vector?

Why does copying eval change its behaviour?

why so many copying while transforming/copying vector

R: Split a Vector into Some Overlapping Sub-vectors with Its First Element being Rebounded

Use Functor / Predicate to find the first element smaller than its predecessor in vector

Why is char* not copying into the vector but string is copied?

Is slicing a vector faster than copying each element into a new vector?

Why is it illegal : copying vector of pointers into a vector of pointers to constants

Find First Missing Element in a vector

First Element of vector with weird data

Range of the first element of a vector pair

r specify the first element in a vector

why vector resize its size when i take input same element in the vecotor

Why is a spread element unsuitable for copying multidimensional arrays?

Why does the access time for the first element of a data.frame depends on its dimensions?

Why mutating the list to be only its first element with this approach does not work in Common Lisp?

If a string in lisp is a vector, why can't I access the first element using svref?

Pushing something into a vector depending on its last element

Get an element from a vector with its attribute in R

Why python executable loses its icon after copying into another folder?

Why does gcc generate a memmove instead of a memcpy for copying a std::vector<>?

Why is this code accessing vector out of its range?

Why queue accepts vector as its underlying container?

Why is my vector dropping its data?

Is the address of an array equal to its first element in C

Check if the element is the first or the last one in an std::vector