0

I have this struct:

typedef struct
{
    UINT8 a;
    UINT8 len;
    BYTE *data;
} MyStruct;

and this binary array [0x00, 0x03, 0x08, 0x09, 0x0a] which is assigned to a void* variable "BINDATA".

How can I cast BINDATA to MyStruct and be able to access its "data" field?

I tried:

MyStruct *myStruct = (MyStruct*) BINDATA;

After that I was able to access:

myStruct->a; //gave me 0x00
myStruct->len; //gave me 0x03

But I could not access

myStruct->data;

without memory access violation. I guess this is because "data" address pointer gets set to 0x08 and not its value.

arminb
  • 2,036
  • 3
  • 24
  • 43
  • 1
    What is ```myStruct->b```? in your struct I cant see b member. –  Aug 12 '16 at 13:39
  • 5
    Undefined behavior for accessing an object through an lvalue not of the effective type of the object. – EOF Aug 12 '16 at 13:40
  • What is `myStruct->data` supposed to be? What is the correct result for this example? – ForceBru Aug 12 '16 at 13:41
  • It is C++ but I wonder if it can be done in C too. – arminb Aug 12 '16 at 13:41
  • `myStruct->data` shall be a pointer to BYTE with following contents: `0x08, 0x09, 0x0a` – arminb Aug 12 '16 at 13:42
  • It's doable with some changes to MyStruct and some packing directives, but the way it is now, you would have to make a new MyStruct and set the pointer to the correct address for "data", as well as initialize the other values. – Kenny Ostrom Aug 12 '16 at 13:43
  • Are you sure pointers are 24 bit on the given system? 16, 32 or 64 bit pointers are much more common. – Lundin Aug 12 '16 at 13:46
  • Show code saving a struct to BINDATA and loading from it. It must be error there. – Anton Malyshev Aug 12 '16 at 13:50
  • This violates [strict aliasing](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule), and so EOF is right in that it's undefined behavior. – AndyG Aug 12 '16 at 13:50

2 Answers2

4

Instead of BYTE *data you should use BYTE data[0] or (if your compiler doesn't like this) BYTE data[1]. The difference between pointer and array here is crucial - array is "data that is right here" while pointer is "data somewhere else" which is not your case.

aragaer
  • 17,238
  • 6
  • 47
  • 49
  • Wow this actually works. But isn't that a little hacky? It looks weird in the code to define data[1]; – arminb Aug 12 '16 at 13:48
  • 1
    @arminb, not at all. You're just putting data in an array, which is OK. – ForceBru Aug 12 '16 at 13:49
  • 2
    @arminb It's called a "flexible array member". It's allowed in C, but not in C++. – Barmar Aug 12 '16 at 13:54
  • @Barmar how do you mean it's not allowed? How do you do this in C++? – arminb Aug 12 '16 at 13:56
  • @arminb In C, you declare the flexible array member with an empty size `BYTE data[]`. That's what isn't allowed. If you declare it with a size, nothing stops you from allocating more space with `malloc()` and writing more elements. But the language doesn't address the proper way to calculate the additional size. – Barmar Aug 12 '16 at 13:59
  • Also C++ `new MyStruct` can't be used to allocate larger space. – Barmar Aug 12 '16 at 14:00
  • In C++ you can use `(MyStruct *) ::operator new(sizeof(MyStruct)+len)` – aragaer Aug 12 '16 at 14:17
-1

Something like this may work in c++:

UINT* a1 = &myStruct->len;
UINT* a2 = ++a1;

Then cast a2 to whatever you want. Be aware of the size and the type of your data.