Assignment of address to integer variable - c++

How come you can assign an address to an integer variable like this,the complier will not give an error. i always though you can only assign integer values to a integer variable
int a=0x28ff1c
You can do the same for a char variable, the complier will not give a error
char b=0x28ff1c
It will output on the console screen rubbish value for char b and a random value for int a
cout<<b
<<endl;
cout<<a;
Can someone explain to me why there is a difference in the output for char b and int a.
Can someone aslo explain to me why a char variable and integer variable can have addresses assign to it

0x28ff1c is not an address itself - it's just a hexadecimal number.
The following are equivalent:
int a = 2686748; //decimal number
int a = 0x28ff1c; //hexadecimal number
int a = 012177434; //octal number
An address is represented by a pointer - if it's just that, an address, you can use a void*:
void* p = (void*)0x28ff1c;
In which case
int a = p;
wouldn't compile. p is an address, the number itself isn't.

The number 0x28ff1c is just the hexadecimal (base-16) representation of the decimal (base-10) number 2686748. As cout defaults to printing decimal values for integers, that is probably the number you got printed.
The case with char b = 0x28ff1c is slightly different, because
char is not large enough to hold that value. The practical result is that it gets truncated to 0x1c.
cout treats char specially, because it is normally used to hold textual data, so cout prints the character that has the code 0x1c, which is some kind of control character. You could try it with 0x41 for example (which represents 'A' in ASCII and UTF-8).
And note that there is nothing that marks 0x28ff1c as being an address. An address would be formed by &a or (void*)0x28ff1c.

Because in any literal starting 0x is actually an integer. So it is allowed. An address is can sometimes be an integer.

You can also use *(int *)(Address) = value as a construct to assigne a value to Address and use the answer by #Luchian Grigore

Related

Assigning an integer to a character variable

I was trying to assign an integer to a char, unsigned char and signed char variables, to understand the results of the same. I am running this code on a 64 bit Mac OS. I am baffled with the response and am looking for someone to help me out with the same. I am not looking at the sizeof result, I am only trying to understand why printing the value of variables result in weird characters.
#include<iostream>
using namespace std;
int main() {
char a = 2;
unsigned char b = 10;
signed char c = 200;
cout<<"Regular char variable value "<<a<<"\t"<<"size of the variable is "<<sizeof(a)<<"\n";
cout<<"Regular char variable value "<<b<<"\t"<<"size of the variable is "<<sizeof(b)<<"\n";
cout<<"Regular char variable value "<<c<<"\t"<<"size of the variable is "<<sizeof(c)<<"\n";
}
And the output of this code is following:
Regular char variable value size of the variable is 1
Regular char variable value
size of the variable is 1
Regular char variable value ? size of the variable is 1
Please note that the 2nd line in the output is garbled, which adds to the complexity of the output.
It is because cout<<a tries to print a as a character instead of a number (the same for b and c).
Looking at an ASCII table
tells you that character 2 is STX, 10 is LINEFEED, and 200 is up in the non-standard special characters section, or would be. Note that you assign 200 to a signed char whose maximum value is 127, so you'll actually end up with a negative number.
Since none of these characters have visible representations on the terminal, you'll see blanks.
To print them in numerical fashion you should use, e.g.
cout<<(int)a;

what is inside skipped memory address?

We know integer variable take 4-byte memory address. I just wonder, if we initialize integer variables and make a pointer to it. I can get the value of it from the pointer (which have the address of the variable: 0x22fef8 in my computer). But how about the memory address after 0x22fef8 which is 0x22fef9, 0x22fefa, 0x22fefb? What is in there? Are we will get the value of the variable if we dereference this address? How to access them?
You're right: in a 32-bit computer an integer takes up four bytes. In C, that can be expressed by the following code:
int i = 0x12345678;
int *p_i = &i;`
If p_i gets the value 0x22fef8, then p_i++ would become 0x22fefc since it would point to the next integer. If you want to see what's in the bytes that make up i, you need to use a different pointer:
typedef uint_8 byte;
byte *p_b = (byte *)&i;`
That means that you change the pointer-to-int that &i represents and typecast it to be a pointer-to-byte. It will still have the value 0x22fef8 since that's where the first byte of i is - but now if you do a p_b++ it will change to 0x22fef9. And note that if you print out the original value of *p_b (that is, the byte that it is pointing to), it will not give the same value as i. Depending on the computer, it will print out either the first byte or the last byte: 0x12 or 0x78, or at least the decimal versions thereof.
This is due to the "endianness" of the computer, which affects the storage of multi-byte values. Little-endian computers like the x86 store the littlest part of the value first - the 0x78 - while Power PC computers store the biggest part of the value first - the 0x12.
int types take up four bytes on your system, so those are all occupied by the int. All are inaccessible except the first one.
It is to note some ints take up two bytes on other systems. It isn't regulated by the standard.
If you want to see the values in those addresses, just do this and you will get values of next 10 addresses
int main()
{
int a = 5;
int *p_i = &a; // The address of 'a' is stored in pointer 'p_i'
// Now you want to check the values in 10 further addresses
for ( int i = 0; i < 10; i++ )
{
int value = *p_i; // Here it is getting the address of pointer as integer value
cout << value << endl;
p_i++;
}
return 0;
}

Display value of Hexa stored in Array

I have and array of hexa values called
const char receiptLogo[] = {0x01,0x80,0x00,0xB4};
When I tried to get the value Rprintf("%x\r\n",receiptLogo[3]);
Value was displayed as "ffffffb4" and sometimes it was displayed as "b4"
The whole Function is as
void PRINT_PrintLogo( const char Data[])
{
unsigned int height=0;
const char receiptLogo[] = {0x01,0x80,0x00,0xB4};
height=(((unsigned short)receiptLogo[2] ) << 8) | ((unsigned short)receiptLogo[3] );
Rprintf("height=%d,%x,%x\r\n",height,Data[2],Data[3]);
}
The output of this function is
height=65460,0,ffffffb4
although in other times the output is height=180,0,b4
Kindly please advise the reason behind it
in printf() the %X format specifier is hexadecimal int. If you pass a char as a parameter and the most significant bit is set it should sign extend to fill the size of an integer. The compiler may optimize by packing variables and sometimes your variable my be in different places with respect to byte boundaries (i.e. the char may end up in the least significant byte or most significant byte of a 32-bit integer). This access may cause this behavior.

Confused in the output of the following programme

float b = 1.0f;
int i = b;
int& j = (int&)i;
cout<<j<<endl;
o/p = 1
But for the following scenario
float b = 1.0f;
int i = b;
int& j = (int&)b;
cout<<j<<endl;
O/P = 1065353216
since both are having the same value it shall show the same result ...Can anyone please let me know whats really happening when i am doing some change in line number 3 ?
In the first one, you are doing everything fine. The compiler is able to convert float b to int i, losing precision, but it's fine. Now, take a look at my debugger window during the execution of your second example:
Sorry for my Russian IDE interface, the first column is variable name, the second is value, and the third is type.
As you can see, now the float is simply interpreted as int. So the leading 1 bits are interpreted as the integer's bits, which leads to the result you are getting. So basically, you take the float's binary representation (usually it's represented as sign bit, mantissa and exponent), and try to interpret it as an int.
In the first case you're initializing j correctly and the cast is superfluous. In the second case you're doing it wrong (i.e. to an object of a different type) but the cast shuts the compiler up.
In this second case, what you get is probably the internal representation of 1.0 interpreted as in integer.
Integer 1 and floating-point 1.0f may be mathematically the same value, but in C++ they have different types, with different representations.
Casting an lvalue to a reference is equivalent to reinterpret_cast; it says "look at whatever is in this memory location, and interpret those bytes as an int".
In the first case, the memory contains an int, so interpreting those bytes as an int gives expected value.
In the second case, the memory contains a float, so you see the bytes (or perhaps just some of them, or perhaps some extra ones too, if sizeof(int) != sizeof(float)) that represent the floating-point number, reinterpreted as an integer.
Your computer probably uses 32-bit int and 32-bit IEEE float representations. The float value 1.0f has a sign bit of zero, an exponent of zero (represented by the 8-bit value 127, or 01111111 in binary), and a mantissa of 1 (represented by the 23-bit value zero), so the 32-bit pattern would look like:
00111111 10000000 00000000 00000000
When reinterpreted as an integer, this gives the hex value 0x3f800000, which is 1065353216 in decimal.
Reference doesn't do any memory allocation, it just places an entry into table of local names and their addresses. In first case name 'j' points to the memory previously allocated to int datatype (for variable 'i'), while in second case name 'j' points to memory allocated to float datatype (for variable 'b'). When you use 'j' compiler interprets data at the appropriate address as if it was int, but in fact some float is placed there, that's why you get some "strange" numbers instead of 1
The first one first casts b to an int before assigning it to i. This is the "proper" way, as the compiler will properly convert the value.
The second one does no casting and re-interpret's b's bits as an integer. If you read up on floating point format you can see exactly why you're getting the value you're getting.
Under the covers, all your variables are just collections of bits. How you interpret those bits changes the perceived value they represent. In the first one, you're rearranging the bit pattern to preserve the "perceived" value (of 1). In the second one, you're not rearranging the bit pattern, and so the perceived value is not properly converted.

what's the size of hex value of some memory address converted to int or other type?

For example:
int* x = new int;
int y = reinterpret_cast<int>(x);
y now holds the integer value of the memory address of variable x.
Variable y is of size int. Will that int size always be large enough to store the converted memory address of ANY TYPE being converted to int?
EDIT:
Or is safer to use long int to avoid a possible loss of data?
EDIT 2: Sorry people, to make this question more understandable the thing I want to find out here is the size of returned HEX value as a number, not size of int nor size of pointer to int but plain hex value. I need to get that value in in human-readable notation. That's why I'm using reinterpret_cast to convert that memory HEX value to DEC value. But to store the value safely I also need to fing out into what kind of variable to it: int, long - what type is big enough?
No, that's not safe. There's no guarantee sizeof(int) == sizeof(int*)
On a 64 bit platform you're almost guaranteed that it's not.
As for the "hexadecimal value" ... I'm not sure what you're talking about. If you're talking about the textual representation of the pointer in hexadecimal ... you'd need a string.
Edit to try and help the OP based on comments:
Because computers don't work in hex. I don't know how else to explain it. An int stores some amount of bits (binary), as does a long. Hexadecimal is a textual representation of those bits (specifically, the base16 representation). strings are used for textual representations of values. If you need a hexadecimal representation of a pointer, you would need to convert that pointer to text (hex).
Here's a c++ example of how you would do that:
test.cpp
#include <string>
#include <iostream>
#include <sstream>
int main()
{
int *p; // declare a pointer to an int.
std::ostringstream oss; // create a stringstream
std::string s; // create a string
// this takes the value of p (the memory address), converts it to
// the hexadecimal textual representation, and puts it in the stream
oss << std::hex << p;
// Get a std::string from the stream
s = oss.str();
// Display the string
std::cout << s << std::endl;
}
Sample output:
roach$ g++ -o test test.cpp
roach$ ./test
0x7fff68e07730
It's worth noting that the same thing is needed when you want to see the base10 (decimal) representation of a number - you have to convert it to a string. Everything in memory is stored in binary (base2)
On most 64-bit targets, int is still 32-bit, while pointer is 64bit, so it won't work.
http://en.wikipedia.org/wiki/64-bit#64-bit_data_models
What you probably want is to use std::ostream's formatting of addresses:
int x(0);
std::cout << &x << '\n';
As to the length of the produced string, you need to determine the size of the respective pointer: for each used byte the output will use two hex digit because each hex digit can represent 16 values. All bytes are typically used even if it is unlikely that you have memory for all bytes e.g. when the size of pointers is 8 bytes as happens on 64 bit systems. This is because the stacks often grow from the biggest address downwards while the executable code start at the beginning of the address range (well, the very first page may be unused to cause segmentation violations if it is touched in any way). Above the executable code live some data segments, followed by the heap, and lots of unused pages.
There is question addressing similar topic:
https://stackoverflow.com/a/2369593/1010666
Summary: do not try to write pointers into non-pointer variable.
If you need to print out the pointer value, there are other solutions.