在使用 fstream 之前读取 mat 期间发生段错误
Segerror occures during mat reading until ostream is used
我有两个 CV_32FC1 Mat flow[0]
和 flow[1]
以这种方式生成
95 cv::gpu::BroxOpticalFlow bof(alpha, gamma, scale_factor, inner_iteratoins, outter_iterations, solver_iterations);
96 bof(gpuFrame[0], gpuFrame[1], gpuFlow[0], gpuFlow[1]);
97
98 cv::Mat flow[2];
99 for(int i=0; i<2; ++i) {
100 gpuFlow[i].download(flow[i]);
101 }
只有第115行和116行都被注释时,才会在第117行出现分段错误。
105 cv::Size flow_size = flow[0].size();
106
107 std::size_t vertices_count = flow_size.width * flow_size.height;
108
109 std::list< int > vertices;
110 for(int j=0; j<flow_size.height; ++j) {
111 const double * x_flow = flow[0].ptr<double>(j);
112 const double * y_flow = flow[1].ptr<double>(j);
113
114 for(int i=0; i<flow_size.width; ++i, ++x_flow, ++y_flow) {
115 //std::cout << i << ' ' << j << std::endl;
116 //std::cout << "|" << std::endl;
117 if(norm(*x_flow, *y_flow) > eps) {
118 vertices.push_back(i + j*flow_size.width);
119 }
120 }
121 }
如果从命令行调用代码,则不会返回任何内容。但是,当程序在 gdb 中执行时,会返回段错误代码。当 115 或 116 取消注释时,一切都很好。
g++版本为4.9.2。使用 CUDA 编译的 OpenCV 2.4.9。使用了 c++11 标志。
CV_32FC1
是 float
,而不是 double
。
改变
const double * x_flow = flow[0].ptr<double>(j);
const double * y_flow = flow[1].ptr<double>(j);
到
const float * x_flow = flow[0].ptr<float>(j);
const float * y_flow = flow[1].ptr<float>(j);
将浮点内存解释为双倍内存意味着您正在为每个像素读取 2 倍的内存块数。因此,如果下一个内存块不属于您的程序,您将走出图像内存并出现段错误。
您正在 *x_flow, *y_flow
访问第 117
行中的元素。
如果您没有遇到段错误,那么您正在 "accidentally" 访问您自己程序的内存,但无论如何您都没有从一开始就读取您想要读取的值。
我有两个 CV_32FC1 Mat flow[0]
和 flow[1]
以这种方式生成
95 cv::gpu::BroxOpticalFlow bof(alpha, gamma, scale_factor, inner_iteratoins, outter_iterations, solver_iterations);
96 bof(gpuFrame[0], gpuFrame[1], gpuFlow[0], gpuFlow[1]);
97
98 cv::Mat flow[2];
99 for(int i=0; i<2; ++i) {
100 gpuFlow[i].download(flow[i]);
101 }
只有第115行和116行都被注释时,才会在第117行出现分段错误。
105 cv::Size flow_size = flow[0].size();
106
107 std::size_t vertices_count = flow_size.width * flow_size.height;
108
109 std::list< int > vertices;
110 for(int j=0; j<flow_size.height; ++j) {
111 const double * x_flow = flow[0].ptr<double>(j);
112 const double * y_flow = flow[1].ptr<double>(j);
113
114 for(int i=0; i<flow_size.width; ++i, ++x_flow, ++y_flow) {
115 //std::cout << i << ' ' << j << std::endl;
116 //std::cout << "|" << std::endl;
117 if(norm(*x_flow, *y_flow) > eps) {
118 vertices.push_back(i + j*flow_size.width);
119 }
120 }
121 }
如果从命令行调用代码,则不会返回任何内容。但是,当程序在 gdb 中执行时,会返回段错误代码。当 115 或 116 取消注释时,一切都很好。
g++版本为4.9.2。使用 CUDA 编译的 OpenCV 2.4.9。使用了 c++11 标志。
CV_32FC1
是 float
,而不是 double
。
改变
const double * x_flow = flow[0].ptr<double>(j);
const double * y_flow = flow[1].ptr<double>(j);
到
const float * x_flow = flow[0].ptr<float>(j);
const float * y_flow = flow[1].ptr<float>(j);
将浮点内存解释为双倍内存意味着您正在为每个像素读取 2 倍的内存块数。因此,如果下一个内存块不属于您的程序,您将走出图像内存并出现段错误。
您正在 *x_flow, *y_flow
访问第 117
行中的元素。
如果您没有遇到段错误,那么您正在 "accidentally" 访问您自己程序的内存,但无论如何您都没有从一开始就读取您想要读取的值。