0

I'm new to C++. And thus also the idea of using pointers. I have some arrays that I want to queue. I understand that my code does not work as I'm using pointers. However I do not know how I should fix this? I need the elements from the queue to be a float* type for later use with BLAS.

#include <iostream>
#include <queue>
using namespace std;


float* initialize(float* vec, int len){
    for(int i = 0; i < len; ++i){
        vec[i] = 0;     // Initialize
    }
    return vec;
}

void printVector(float* vec, int len){
    for(int i=0;i<len;i++)
        cout << vec[i] << endl;
    cout << "--" << endl;
}

int main ()
{
    queue<float*> q;
    int len = 3;
    float* k = new float[len];
    k = initialize(k,len);

    for(int t=0;t<len;t++){
        k[t] = 1;   
        printVector(k, len);
        q.push(k);
        k[t] = 0;
    }

    // I would like the one below to give same output as above
    cout << "Should have been the same:" << endl;

    while (!q.empty()){
        printVector(q.front(), len);
        q.pop();
    }

    return 0;
}

Bonus question does these types of "pointer arrays" have a special name? float* k = new float[len];

7
  • You could use std::vector<float>. If you have to pass C arrays to BLAS functions you could extract them using std::vector::data() (or &std::vector::operator[0]). The size (number of elements) (which is probably required as well) is available with std::vector::size(). Commented Jun 11, 2018 at 14:03
  • k is just a pointer to the first element of the new array. It is indistinguishable from a pointer to any other float, except in what you can/must do with it. Commented Jun 11, 2018 at 14:03
  • Thanks. And yes, I understand that. However, I do not know how to come around this if I want q.front() to be a float*. Commented Jun 11, 2018 at 14:07
  • @Christian you probably don't need that. If you used a std::queue<std::vector<float>> you could just as easily do q.front().data(). Commented Jun 11, 2018 at 14:09
  • In general, you can do it the way you tried BUT: you allocate storage only once. To make it working you have to allocate storage in the loop (the one with the q.push();). The other loop should delete[] the popped pointer resp. (Otherwise you might get memory leaks.) As you did it, all queue entries share the same storage (and hence the side effects). => Assigning a pointer does not copy the pointed contents. Commented Jun 11, 2018 at 14:09

1 Answer 1

2

The essential message is: Storing a pointer (to an array or what ever) does not copy the contents. It just copies the address of it.

Re-ordering your statements a bit I got OP's sample running (and doing what's probably intended):

#include <iostream>
#include <queue>
using namespace std;


float* initialize(float* vec, int len){
    for(int i = 0; i < len; ++i){
        vec[i] = 0;     // Initialize
    }
    return vec;
}

void printVector(float* vec, int len){
    for(int i=0;i<len;i++)
        cout << vec[i] << endl;
    cout << "--" << endl;
}

int main ()
{
    queue<float*> q;
    int len = 3;

    for(int t=0;t<len;t++){
        float* k = new float[len];
        k = initialize(k,len);
        k[t] = 1;   
        printVector(k, len);
        q.push(k);
    }

    // I would like the one below to give same output as above
    cout << "Should have been the same:" << endl;

    while (!q.empty()){
        printVector(q.front(), len);
        delete[] q.front();
        q.pop();
    }

    return 0;
}

Output:

1
0
0
--
0
1
0
--
0
0
1
--
Should have been the same:
1
0
0
--
0
1
0
--
0
0
1
--

Using new in C++ is error prone and can be prevented in many cases. Doing the same with std::vector<float>, it could look like this:

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

void printVector(const float* vec, int len){
    for(int i=0;i<len;i++)
        cout << vec[i] << endl;
    cout << "--" << endl;
}

int main ()
{
    queue<std::vector<float> > q;
    int len = 3;

    for(int t=0;t<len;t++){
        q.push(std::vector<float>(3, 0.0f));
        q.back()[t] = 1.0f;
        printVector(q.back().data(), q.back().size());
    }

    // I would like the one below to give same output as above
    cout << "Should have been the same:" << endl;

    while (!q.empty()){
        printVector(q.front().data(), q.front().size());
        q.pop();
    }

    return 0;
}

Output is identical.

Live Demo on coliru

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Scheff! Exactly what I was looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.