# How to get 4 bytes from an unsigned char pointer and convert to int?

Hi Guys,
I have code like this:

unsigned char *pBuff;

pBuff is assigned to something;

Now, I want to get the first 4 bytes from that pBuff and save it as an int type, i.e. :

int iValue = // the first 4 bytes from pBuff;

How do I do it please?

Thanks,
BB
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
If you have 32-bit integers and pBuf points to a 32-bit integer with the appropriate endianism, you can simply write:

int i = *reinterpret_cast<int*>(pBuff);
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Author Commented:
well, my pBuff can be more than 32-bit and I only want to get the 4 bytes from where it is pointing to.
0
Commented:
it might be possable to say:

unsigned char *pBuff;
int iValue;

for (int I=0;I<4:i++){
iValue=*pBuff[I]
}

try that and see what happens
0
Author Commented:
Dawaffleman,
If I do that, then I will get the fourth element from the pBuff, which is not what I want.
0
Commented:
well if each element was one byte which a character is (correct?) then it should get the fourth byte, or charater
0
Author Commented:
but the fourth byte is different than 4 bytes. I want to be able to get all 4 bytes.
0
Commented:
oh i see, my mistake heh.

well then maybe you could make a union... i dont know the EXACT syntax becuase ive never had to use it, but it goes something like this

union myUnion{
int myVal;              //four bytes
char byte1;          //first of four bytes
char byte2;           //second
char byte3;          //third
char byte4;           //fourth
};

then you could go:

myUnion myValue;
myValue.byte1=*pBuff[0];
myValue.byte2=*pBuff[1];
myValue.byte3=*pBuff[2];
myValue.byte4=*pBuff[3];

that should work, theoretically. if you dont know what a union is its basically a structure, but more compact. the size of the union is the size of the largest member (in this case int). the other values will then share this same data space for thier own values. remember that i dont know if thats exactly what you need but i would guess it would be something very close to that.

0
Commented:
>>my pBuff can be more than 32-bit and I only want to get the 4 bytes from where it is pointing to

rstaveley is absolutely on point. His solution will perform exactly what you want. Just my 2 Cents.... :o)
0
Author Commented:
I just don't feel safe to use this casting operation. Is there any other way to do it such as shifting the bits? Thanks
0
Commented:
It is the easiest way apart from

int i;

memcpy(&p,pBuff,sizeof(int));

which will do the same - in fact, that's similar to what the compiler will generate when you use the cast.
0
Commented:
Oosp, that should have been

int i;

memcpy(&i,pBuff,sizeof(int));
0
Commented:
#include <stdio.h>

union U
{
int val;
char buf[sizeof(int)];//of buf[4]
};

int main(void) {

char *pBuf="0123456789";

U u;
for(int i = 0; i < sizeof(int); ++i)
u.buf[i] = pBuf[i];

printf("%x\n", u.val);
return 0;

}

_novi_
0
Commented:
>>     for(int i = 0; i < sizeof(int); ++i)
>>         u.buf[i] = pBuf[i];

You aren't *really* serious to suggest that loop over 'memcpy()' or the cast, are you?
0
Commented:
If you're sure that sizeof(int) on your system or platform is really 4 bytes and not more, then i recommend rstaveley's answer, if not, then you might want jkr's. if you really want 4 bytes no matter what, then you might consider using long instead of int because long is guaranteed to be 4 bytes in size.

Anyway, i think your question is sufficiently answered, and, if i may add, with standard, easy and, contrary to your fears, safe approaches. I can't understand why you would want something that is obscure like bit shifting.

;)
0
Commented:
> I just don't feel safe to use this casting operation.

Is that because you've yet to get your head round it or that you understand it, but feel that it is not doing what you want?

> pBuff can be more than 32-bit

I assume you mean that pBuff points to an array of more than four unsigned chars. That's not a problem. Provided the first 32 bits (i.e. 4 bytes) contain your integer, your system has a 32 bit word size (i.e. sizeof(int) == 4) and your integer has its bits in the correct order for your system (e.g. is little endian on Intel), the cast will work. reinterpret_cast<int*> says that the compiler should treat pBuff as a pointer to int. By dereferencing the reinterpreted pointer you are asking the value of the pointed-to integer to be taken.
0
Commented:
>>>> I just don't feel safe to use this casting operation.

Why cast at all?

int temp = pBuff[0];

Regards, Alex

0
Commented:
Still uses casts but may be tidier:

char fourBytes[sizeof(int)] = {0x11,0x22,0x33,0x44};
int integer = *((int*)fourBytes);

Paul
0
Commented:

unsigned arr[] = { 3123456789, 3123456789, };
int  x  = arr[0];
int  y  = *arr;
int  z  = *(reinterpret_cast<int*> (arr));

After that, x, y, and z have the same value. That means, all is equivalent.

You don't need a cast to get what you want.

Regards, Alex
0
Author Commented:
> Is that because you've yet to get your head round it or that you understand it, but feel that it is not doing what you want?

According to what I read from the MSDN lib:
"reinterpret_cast Operator
The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

Syntax

reinterpret_cast < type-id > ( expression )

The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

The reinterpret_cast operator cannot cast away the const, volatile, or __unaligned attributes. See const_cast Operator for information on removing these attributes.

The reinterpret_cast operator converts a null pointer value to the null pointer value of the destination type."

> memcpy(&i,pBuff,sizeof(int));

I have been playing with the memcpy, but do I need to do the ntohl after all?
0
Commented:
>>>> I have been playing with the memcpy, but do I need to do the ntohl after all?

Nope, the byte order isn't different between unsigned int and int.

The only difference is the interpretation of the most highest bit that is used as sign bit for integers.

>>>> I have been playing with the memcpy

Again, you *don't* need memcpy or casting to assign between int and unsigned int. A simple

int i = *pBuff;

is all you need (I wonder if you'll trust me this time ...)

Regards, Alex

0
Commented:
Hey BooBoo,

msdn may be right to call reinterpret_cast unsafe but, what you obviously failed to read between the lines is that casting from any pointer type to another pointer type is generally considered unsafe. This is one of the reasons why most other languages did away with pointers and casting a long time ago. Because you are trying to convert the dereferenced value of type char* to type int, you are already 'implicitly' performing a CASTING operation, no matter what method you opt to use. Now using reinterpret_cast does not guarantee safety of an already unsafe practice but at least, it tells the compiler in a no-nonsense way what you intend to do and warns other programmers reading your code that they are stepping into danger zone.

ALex, you can't do this:

int i = *pBuff

because BooBoo's pBuff is of type unsigned char *pBuff, unless you want the c++ compiler to spit on you. ;')

---doc

P.S. Aren't we all glad that we can do all kinds of wonderful stuff (including pointer acrobatics) they can't do on the 'other languages'? Responsibilty is something to be always remembered.
0
Commented:
Ooops Alex, sorry. What I meant you can't do is your earlier post:

int i = *pBuff[0];

which is illegal. Now for

int i = *pBuff;

you will only be getting the first byte pointed to by pBuff and not the 4 bytes that BooBoo originally wanted. ;)
0
Commented:
> Unless the desired conversion is inherently low-level

The desired conversion that *is* inherently low-level. You have an array of unsigned chars. You are telling the compiler that you know best and that the first four bytes of that array are the bit pattern for an integer of appropriate endianism and correct number of bits.

Using reinterpret_cast<> is the best means at your disposal to say that you know better than the compiler. You can also use a C-style cast, but it is less obvious to a subsequent code reviewer what you are doing.

Consider....

// This should look alarming, you are reinterpretting the meaning of the bits.
// For your requirement is correct. You are saying that you do indeed
// know that the bit pattern should be reinterpretated as a different type.
int i = *reinterpret_cast<int*>(pBuff);

// This is less obviously a bit reinterpretation though that's what happens.
// A quick look at the syntax doesn't immediately tell you that
// it is a reinterpret_cast<> rather than a static_cast<> or const_cast<>.
// It is the C programmer's approach, because C programmers
// are linguistically impoverished ;-)
// The gerenated code (or lack of it!) is the same as the reinterpret_cast<>
// but this is not the approach you should adopt for C++.
int i = *(int*)pBuff;

> Other uses are, at best, nonportable

That's correct. Another system might have 16 or 64 bit integers. The data read into the array might have come from a big-endian system and you are reading it into a little endian system. reinterpret_cast<> says you know that the bit pattern is right for the system for which you are compiling code. Same story for your memcpy() implementation. Passing binary data between systems is much trickier than ASCII text, which is why you get so many text-based protocols on the Internet.
0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.