casting problem

H

Harry

Hi ppl

Some problem regarding pointer:


ULONG *addr;
CHAR *ptr=NULL;
addr=new ULONG;
//calling a function and getting the addr value
//ULONG is 4 bytes. I am getting the Ip address which is naturally 4
bytes and
//storing the value in the location given by addr
ptr=(char *)addr;

printf("\n%X\n",*addr); //gives the IP address correctly. total 32
bits

//next line is the problem
printf("%X.%X.%X.%X\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3));

The above line should give the same value as *addr. But its reading
wrongly from the memory. First the byte position have interchanged(i
converted it to network order and saved this value in addr and *addr
gives the network order but the last line is printing in host order).
Secondly, the last byte read is garbage.

any suggestions??...basically i want to convert the ULONG into
CHAR[4]. Any other way to do it i.e. without casting??

thanks
Harry
 
T

Thomas Maier-Komor

Harry said:
any suggestions??...basically i want to convert the ULONG into
CHAR[4]. Any other way to do it i.e. without casting??

thanks
Harry

what about a union?

union
{
ULONG u;
CHAR c[4];
} an_ip_address;
 
P

Peter Koch Larsen

Harry said:
Hi ppl

Some problem regarding pointer:


ULONG *addr;
CHAR *ptr=NULL;
addr=new ULONG;
//calling a function and getting the addr value
//ULONG is 4 bytes. I am getting the Ip address which is naturally 4
bytes and
//storing the value in the location given by addr
ptr=(char *)addr;

printf("\n%X\n",*addr); //gives the IP address correctly. total 32
bits

so it seems that *addr holds the ip-address.
//next line is the problem
printf("%X.%X.%X.%X\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3));

The above line should give the same value as *addr. But its reading
wrongly from the memory. First the byte position have interchanged(i
converted it to network order and saved this value in addr and *addr
gives the network order but the last line is printing in host order).
Secondly, the last byte read is garbage.

any suggestions??...basically i want to convert the ULONG into
CHAR[4]. Any other way to do it i.e. without casting??

Why CHAR?? I would presume a char is correct. Without knowing what a CHAR
is, i don't know if that is bothering you. Another thing i fail to
understand why you do not simply use simple arithmetic (division and
modulus) to get your ipadress. This way you do not have to rely on any
spicific byte order.

thanks
Harry

/Peter
 
R

Ron Natalie

Harry wrote:

There is no type called CHAR or ULONG. It would be nice if you
stuck to real C++ types or told us the nature of any types
you introduce.
CHAR *ptr=NULL;
addr=new ULONG;
ptr=(char *)addr;

printf("\n%X\n",*addr); //gives the IP address correctly. total 32
bits

//next line is the problem
printf("%X.%X.%X.%X\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3));
The above line should give the same value as *addr. But its reading
wrongly from the memory. First the byte position have interchanged(i
converted it to network order and saved this value in addr and *addr
gives the network order but the last line is printing in host order).
Secondly, the last byte read is garbage.

First, I would use (unsigned char*) rather than (char*). It is possible
that the char type is signed. When you pass a char to a vararg'd function
like printf, the char is widened to int. If the char value happens to be
one that is negative you might get unexpected answers.

You most certainly have a byte ordering issue that's unrelated to casting.
You haven't shown us your "converted to network order" but I suspect you've
made an error there. On an LSB-first machine (like Intel processors typically)
ptr[1] will be the low order byte. The question is also whether the addr
as ULONG was already in the proper byte order or not.

The way to do this without casting is to use shifts (which also potentially
gets around the byte ordering issues).

printf("%X.%X.%X.%X\n", (x >> 24) & 0xFF, (x >> 16) & 0xFF, (x>>8) & 0xFF, x&0xFF);
 
V

Victor Bazarov

Harry said:
Hi ppl

Some problem regarding pointer:


ULONG *addr;
CHAR *ptr=NULL;
addr=new ULONG;
//calling a function and getting the addr value
//ULONG is 4 bytes. I am getting the Ip address which is naturally 4
bytes and
//storing the value in the location given by addr
ptr=(char *)addr;

Should probably be

ptr = (CHAR*)addr;

Why do you need all this dancing with 'new'? Just do (I will use your
notation for types, although here they require definition):

ULONG addr;
// retrieve the IP address _into_ 'addr', not into '*addr', no "new"
CHAR *ptr = &addr;
printf("\n%X\n",*addr); //gives the IP address correctly. total 32
bits

With my correction you would do

printf("\n%X\n", addr);
//next line is the problem
printf("%X.%X.%X.%X\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3));

The above line should give the same value as *addr. But its reading
wrongly from the memory. First the byte position have interchanged(i
converted it to network order and saved this value in addr and *addr
gives the network order but the last line is printing in host order).

Endianness is an implementation detail and if you get the wrong order,
just invert it.
Secondly, the last byte read is garbage.

I don't understand that statement.
any suggestions??...basically i want to convert the ULONG into
CHAR[4]. Any other way to do it i.e. without casting??

Definitely. Now I'll use normal type notation:

typedef unsigned long ulong;
typedef unsigne char uchar;
ulong addr = 0x12345678;
uchar ptr[4] = {(addr & 0xff000000UL) >> 24,
(addr & 0xff0000UL) >> 16,
(addr & 0xff00U) >> 8,
(addr & 0xff) };
printf("%X.%X.%X.%X\n", ptr[0], ptr[1], ptr[2], ptr[3]);

(assuming that your 'char' is 8 bits).

Should print
12.34.56.78

(although you should consider %u format because it's the decimal you
need in a dot notation, not hex)

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,965
Members
47,512
Latest member
FinleyNick

Latest Threads

Top