Search code examples
c++c++11stdvectorcout

How does C++ handle vectors when passing from a function to main?


I'm seeing strange behaviour in the output of a 'simple' function that generates the binary representation of an integer. I aim to use the function in another code, but first want to see it working by printing to the console. I first define the function dec2bin to take a number and the length of the required bitstring. After defining a vector that will be returned by the function, the vector is populated with the required binary values. In the main function, the vector is accessed and printed element-wise to the console. However, the output is incorrect unless I include an arbitrary cout statement within the vector populating for loop.

The function is defined as follows:

vector<int> dec2bin(int N, int j){
    vector<int> myvec;
    myvec.push_back(N);
    for (int i = N-1; i >= 0; i--) {
        int r = j >> i;
        if (r & 1)
            myvec[N-i-1] = 1;
        else 
            myvec[N-i-1] = 0;
        //cout << " ";
    }
    return myvec;
}

My main function is:

int main(){
    int length = 8;
    int num = 15;
    vector<int> myvec = dec2bin(length,num);
    for (int j=0; j<length; j++){cout << myvec[j];}
    return 0;
}

When the commented out line (cout << " ") is included within the for loop the output is correct, with 00001111. Without that line (or with the line outside of the for loop) the output is incorrectly 00001141130.

I have read various things about pointers and memory allocation, so expect this is where I am going wrong; however, I can't quite see how to incorporate those ideas into my own code. Any advice would be greatly appreciated, many thanks.


Solution

  • On this line:

    myvec[N-i-1] = 1;
    

    You are invoking undefined behavior for any index other than 0.

    myvec.push_back(N); pushes a single element to the vector, and you never add more elements to the vector. When you access a vector out of bounds, you will not get a compiler error or runtime exception, but your code has undefined behavior, which means the output could be literally anything.

    Actually, it seems like you just confused push_back() with resize(). And instead of resize(), you can pass the size to the constructor. If you replace:

    vector<int> myvec;
    myvec.push_back(N);
    

    with:

    std::vector<int> myvec(N);
    

    or:

    std::vector<int> myvec;
    myvec.resize(N);
    

    You get a vector with N elements, and accessing myvec[i] is fine for any index 0 <= i < N. Alternatively, you could call myvec.reserve(10) to let the vector allocate space for N elements. The vector will then still be empty, and you have to push_back() any element you want to add.