I want get the row number of data, but the pointer CvMat* data, CvMat* responses
get nothing in main()
. The minimal, complete and varifiable example is showed as follow:
#include "opencv2/core/core_c.h"
#include "opencv2/ml/ml.hpp"
#include <cstdio>
#include <fstream>
#include <iomanip>
#define ATTRIBUTES_PER_SAMPLE 9
#define NUM_OF_ALL_SAMPLES 950
using namespace std;
int read_data( CvMat* data, CvMat* responses )
{
float temp=1.0;
data = cvCreateMat( NUM_OF_ALL_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32F );
responses = cvCreateMat( NUM_OF_ALL_SAMPLES, 1, CV_32F );
for(int line = 0; line < NUM_OF_ALL_SAMPLES; line++)
for(int attribute = 0; attribute <= ATTRIBUTES_PER_SAMPLE ; attribute++){
if(attribute < ATTRIBUTES_PER_SAMPLE){
CV_MAT_ELEM(*data, float, line, attribute) = temp;
}
else if(attribute == ATTRIBUTES_PER_SAMPLE){
CV_MAT_ELEM(*responses, float, line, 0) = temp;
}
}
return 1;
}
///////////////////////////////////////////////////////////////////////////
int main()
{
CvMat* data = 0;
CvMat* responses = 0;
int ok = read_data(data, responses);
int nsamples_all = data->rows; // <--------- error happens here
cvReleaseMat(&data);
cvReleaseMat(&responses);
return 0;
return 0;
}
The error is
Unhandled exception at 0x013715c2 in opencv_pointer.exe: 0xC0000005: Access violation reading location 0x00000014.
My compiler is VS2008. Why do the the pointer CvMat* data, CvMat* responses
get nothing?
Because the arguments are passed by value. You can use reference to have callee modify caller's local variables like this (add &
):
int read_data( CvMat*& data, CvMat*& responses )
{
// the same code
}
The parameter data
and responses
are declared to be passed by value, which means any modification on themselves (not the pointee) inside read_data()
would not affect the variables in main()
, their value are still the initialized value 0
.
You could change the parameter type to be passed by reference (or passed by pointer, relevant code needs adjustment for it).
int read_data( CvMat*& data, CvMat*& responses )
~ ~
{
...
}
The parameters are passed by copy so the pointer CvMat* data
in the function is copy of the pointer you pass in from main. Any changes you make to it are local to the function. When you assign it a value using cvCreateMat()
that value is not reflected back to the CvMat* data
in main()
so it gets lost when the function returns.
If you want changes to the parameter to be "passed back" you need to pass in the pointers by reference:
// pass variables by reference using &
int read_data(CvMat*& data, CvMat*& responses)
Now changes made to the parameters inside the function happen to the variables you passed in from outside the function - the pointers are not copied, they are referenced.
User contributions licensed under CC BY-SA 3.0