Ask Your Question
-1

Mat Template Pointer is NULL

asked 2017-12-07 13:40:38 -0600

epatton gravatar image

updated 2017-12-07 13:42:18 -0600

I'm trying to allocate space for a Mat object and access the data via a pointer. I discovered that my pointer was NULL. I'm confused because reserve() should allocate rows yet the ptr is still NULL.

The only thing I've found that works is pushing a value on Mat. Unfortunately that means I've got one extra value in the array. Is there a way I can get a valid pointer without pushing data?

Mat_<int>B;
B.reserve(10);   // This should allocate space so I should get a NULL ptr right?
int *pB = B.ptr<int>(0);  // here pB = NULL. Arg.
pB = (int *)B.data;         // here pB = NULL. Arg.

B.push_back(4);  
pB = B.ptr<int>(0);  // pB != NULL
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-12-07 13:56:32 -0600

berak gravatar image

updated 2017-12-07 13:58:40 -0600

reserve() does NOT allocate any data. the correct way to do this would be:

// a row vector, 
Mat_<int> B(1,10); 
int *pB = B.ptr<int>(0);
// now it's safe to iterate from pb[0] to pb[9]  

// a col vector
Mat_<int> B(10,1); 
int *pB = B.ptr<int>(i);
// careful, all you can use is pb[0] !

Mat is essentially a 2d container, if you want it to behave like a std::vector, why not use one in the 1st place ?

edit flag offensive delete link more

Comments

Thanks Berak. The reason for not using std::vector is because I'm not able to set a pointer to walk through the data. I created a test app and found that although they specify a vector as being continuous memory, I'm unable to walk a pointer through the data successfully. The code below outputs junk when I use the pointer and correct data (all zeros) when I use the vector. I'd like to use the pointer approach because I'm writing a tight processing loop.

 std::vector<int>C(10);
int *pC = &C[0];  // this doesn't work either
pC = (int *)C.data();

cout << "using pointer C = ";
for( int ii = 0; ii < C.size(); ii++){
    cout << pC[ii] << " ";
}
cout << endl;

cout << "C = ";
for( int ii = 0; ii < C.size(); ii++){
    cout << C[ii] << endl; }
epatton gravatar imageepatton ( 2017-12-07 19:18:11 -0600 )edit

"The code below outputs junk when I use the pointer and correct data (all zeros) " -- you're wrong, the data is not set to 0 automatically

berak gravatar imageberak ( 2017-12-08 00:37:44 -0600 )edit

The following code works perfectly:

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

int main(void)
{
    vector<int> vec(10, 0); // Set values to 0 by default.
    vec[vec.size() - 1] = 123456; // Set last value.
    int *pvec = &vec[0]; // Get pointer to vector contents

    for (size_t i = 0; i < vec.size(); i++)
    {
        cout << *pvec << endl;
        pvec++;
    }

    return 0;
}
sjhalayka gravatar imagesjhalayka ( 2017-12-08 19:11:03 -0600 )edit

Thanks for you help on this.
I figured out what was screwing up my code. I had a C.push_back(1) after the pointer was assigned. Since vectors try to use continuous memory, the push_back must have triggered a mem alloc and copy to the new memory. My pointer was basically pointing at the old memory (just a theory).

 std::vector<int>C(10);
 int *pC;
pC = &C[0];  // Bad! Since vectors use continuous memory, the push_back triggered the allocation of new memory for C thus making the pointer invalid; 
C.push_back(99);    
pC = &C[0];  // Good, this gives us the correct memory location because it's done after the push.

cout << "using pointer C = ";
for( int ii = 0; ii < C.size(); ii++){
    cout << pC[ii] << " ";
}
cout << endl;
epatton gravatar imageepatton ( 2017-12-11 16:30:03 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-12-07 13:40:38 -0600

Seen: 1,246 times

Last updated: Dec 07 '17