简体   繁体   中英

Why can't I access this uchar array?

The code:

unsigned char data[20][20] = 
  {{50, 50....},
  ....
  ....};

Mat speed(20, 20, data);

When I try to access contents in speed.data , it says:

Exception thrown at 0x003D2094 in speed tracking.exe: 0xC0000005: Access violation reading location 0x32323233.

For example, std::cout << img.data[0][1]; .

In another file mat.h , the definition of Mat is:

// 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
};

So why can't I access contents in speed.data ?

In fact, you do the incorrect cast assigning Mat::data = data because the left side has the type of unsigned char** and the right side has the type of unsigned char (*)[20] .

Suppose that after such error-prone casting you try to access some array elements via Mat::data , for example evaluating Mat::data[0][1] (which is a bad idea, of course).

Recall that Mat::data[0][1] = *(*(Mat::data + 0) + 1) .

Mat::data + 0 has the type of unsigned char** and value which is equal to the address of the data array.

Then *(Mat::data + 0) has the type of unsigned char* and value which we'll calculate now.

As I can see from the posted crash report, on your machine addresses are 4-byte long. So the first 4 elements of data array are treated as the value of *(Mat::data + 0) . Then we add 1 ( sizeof(char) ) and get *(Mat::data + 0) + 1 value. The result in 16-base is equal to 0x32323233. After that we try to read something from this location, which is the actual reason of SIGSEGV .

It's better to store the address of the first element of array using unsigned char* and use matrix width and height, which are known, to get appropriate matrix elements.

Mat expects a flat array, so replace unsigned char** data in class Mat with unsigned char* .

The data at (x,y) can be accessed using data + x * cols + y .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM