代码:
unsigned char data[20][20] =
{{50, 50....},
....
....};
Mat speed(20, 20, data);
当我尝试访问speed.data
中的内容时,它会说:
在speed tracking.exe中0x003D2094处抛出异常:0xC0000005:访问冲突读取位置0x32323233。
例如,std::cout << img.data[0][1];
。
在另一个文件mat.h
中,Mat
的定义是:
// two-dimensional matrix, type of data is unsigned char
class Mat {
public:
Mat(size_t rows_, size_t cols_, void* data_ = nullptr)
: rows(rows_), cols(cols_), data((unsigned char**)data_) {}
Mat() : rows(0), cols(0), data(nullptr) {}
bool empty() const; // return true if data == nullptr
size_t rows, cols; // the size of the matrix
unsigned char** data; // the contents of the matrix
};
那么为什么我无法访问speed.data
中的内容?
答案 0 :(得分:4)
实际上,您执行了错误的转换分配Mat::data = data
,因为左侧的类型为unsigned char**
,右侧的类型为unsigned char (*)[20]
。
假设在这样容易出错的演员之后你尝试通过Mat::data
访问一些数组元素,例如评估Mat::data[0][1]
(当然这是一个坏主意)。
回想一下Mat::data[0][1] = *(*(Mat::data + 0) + 1)
。
Mat::data + 0
的类型为unsigned char**
,其值等于data
数组的地址。
然后*(Mat::data + 0)
的{{1}}类型和我们现在计算的值。
从发布的崩溃报告中可以看出,您的计算机地址长度为4个字节。因此unsigned char*
数组的前4个元素被视为data
的值。然后我们添加1(*(Mat::data + 0)
)并获得sizeof(char)
值。 16个碱基的结果等于0x32323233。之后我们尝试从这个位置读取一些内容,这是*(Mat::data + 0) + 1
的实际原因。
最好使用SIGSEGV
存储数组的第一个元素的地址,并使用已知的矩阵宽度和高度来获得适当的矩阵元素。
答案 1 :(得分:2)
Mat
需要一个平面数组,因此请将unsigned char** data
中的class Mat
替换为unsigned char*
。
可以使用(x,y)
访问data + x * cols + y
处的数据。