2

I am reading in binary data from a file:

char* buffIn = new char[8];
ifstream inFile(path, ifstream::binary);
inFile.read(buffIn, 8);

I then want to convert the char* read in (as binary) to an unsigned long but I am having problems - I am not quite sure what is going on, but for instance 0x00000000000ACD gets interpreted as 0xFFFFFFFFFFFFCD - I suspect all the 0x00 bytes are causing some sort of problem when converting from char* to unsigned long...

unsigned long number = *(buffIn);

How do I do this properly?

1
  • I wanted to suggest a solution but the question is already closed.:) Commented Feb 26, 2014 at 0:41

3 Answers 3

5

Since buffIn is of type char pointer, when you do *(buffIn) you are just grabbing one character. You have to reinterpret the memory address as an unsigned long pointer and then dereference it.

unsigned long number = *((unsigned long*)buffIn);
Sign up to request clarification or add additional context in comments.

9 Comments

This according to the standards will be undefined behavior. char pointer need not have to be aligned to integer boundary.
Yes, I suppose that is obvious when you think about it. Thanks, will accept when I can.
@Sundar, it is aligned when pointing to allocated memory. Guaranteed by the standard. If the allocated memory is greater than unsigned longof course.
@Nick start of the allocated memory (using malloc/calloc) is always aligned to the max possible pointer boundary (perhaps long long), but not the memory not allocated by malloc/calloc. securecoding.cert.org/confluence/display/seccode/…
@Sundar, from the standard: 1 Effects: The allocation function (3.7.3.1) called by a new-expression (5.3.4) to allocate size bytes of storage suitably aligned to represent any object of that size.
|
0

In addition to recasting the char[8] (which will only read the the first unsigned long - which is 32-bits in length), you can also use some simple bit-wise operations

unsigned long value = (((unsigned long)buffin[0]) << 24) | (((unsigned long)buffin[1]) << 16) | (((unsigned long)buffin[2]) << 8) | (unsigned long)buffin[3];

2 Comments

The unsigned longs are 64 bit on this platform. It's not meant to be portable code :)
@adrianmcmenamin Then you can do the same thing, just change the coefficients for the bit shifts.
0

Try something like

unsigned long* buffInL = new unsigned long[2];
char* buffIn=(char*)buffInL;
ifstream inFile(path, ifstream::binary);
inFile.read(buffIn, 8);

Unlike other types, char* is allowed to alias.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.