Ming Wei
Ming Wei

Reputation: 148

Reinterpret 2d array as pointer

Assume I have an array like this:

unsigned char a[10][10];

and I want to use fread to read bytes into this array (row-major order):

FILE *f = fopen("xxx.bin", "rb");
fread((unsigned char *)a, 1, 10 * 10, f);
fclose(f);

As the first parameter of fread is of type void *, is there a standard way to convert unsigned char a[10][10] to void *? Should I use static_cast or reinterpret_cast or? As 2d-arrays in c++ are allocated consecutively, I think it is reasonable to reinterpret it as pointers.

Upvotes: 0

Views: 545

Answers (2)

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17415

In order to get a void* pointing at a, just take its address (&a) and let the compiler do the implicit conversion to void*:

fread(&a, sizeof a, 1, f);

There are a few caveats/notes:

  • Firstly, you take the pain to close the file, but you fail to check for read errors.
  • Whenever you use reinterpret_cast, the only way to use the result is to reinterpret_cast it back to the exact former type. In general, you don't use reinterpret_cast therefore, unless you need to e.g. store a pointer in an integer. static_cast is the way to go, as others mentioned.
  • Never use C-style cast. They are dangerous and they don't document what's going on at all. FWIW, you could const-decorate your array and your code would happily compile and break at runtime, because you overrode the safety-switch of the compiler.
  • I wouldn't count on having no padding between the rows of the matrix, i.e. its size wouldn't be just 100. You can only solve that using separate read operations for each row. I'm not sure about this point though, it could well be that its size is guaranteed to not include any padding.

Upvotes: 2

justanothercoder
justanothercoder

Reputation: 1890

The following works in gcc 4.8.2:

FILE *f = fopen("xxx.bin", "rb");
fread(a, sizeof(unsigned char), 10 * 10, f);
fclose(f);

If you prefer explicit casts, then standard way is to use static_cast. It should be used because it preserves address when casting to void*.

FILE *f = fopen("xxx.bin", "rb");
fread(static_cast<void*>(a), sizeof(unsigned char), 10 * 10, f);
fclose(f);

reinterpret_cast only guarantees that if you cast something to void* and then cast back to your type, then you will get the same value.

Upvotes: 1

Related Questions