Reputation: 14811
Background: I work a lot with binary data, and I often need to work with raw pointers. I also often need the size so that I can check if I read/write off the bounds (reasonable, right?). Now I'm trying to create a syntactic sugar class for pointers that holds size of the underlying data so that I can simplify function declarations.
Demonstration of the problem - the code behind my class that crashes can be simplified to this:
char *a = (char*) malloc(4); // some underlying data
strncpy(a, "1234", 4); // that is not statically linked so it can be written to
uint32_t *ptr = reinterpret_cast<uint32_t*>(a);
ptr[0] = 1234; // works
reinterpret_cast<int&>(ptr[0]) = 1234; // curiously, this works too
*reinterpret_cast<int*>(ptr[0]) = 1234; // this crashes the program
printf("%d\n", ptr[0]);
The program above crashes as described in comments. Valgrind outputs following:
Invalid write of size 4
at 0x40064A: main (in /home/rr-/test)
Address 0x4d2 is not stack'd, malloc'd or (recently) free'd
I suspect I'm violating the strict aliasing rule, but:
char*
for underlying structure. Most likely, it doesn't matter because what I'm reinterpret_cast
ing isn't a char*
but a uint32_t*
and compiler doesn't care what uint32_t*
originally pointed at.-fno-strict-aliasing
and -fstrict-aliasing
, the program crashes all the same... (I compile the program with g++ 5.2.0 under GNU/Linux.)Can someone tell where did I go wrong, and how can I correct this problem?
Upvotes: 0
Views: 1356
Reputation: 92271
You just stored 1234 in ptr[0]
. Then you cast the 1234 into a pointer and dereference it.
That tries to access address 1234, which doesn't work.
Upvotes: 1