#include <iostream>
using namespace std;
int main(int argc, char** argv) {
unsigned int a =5;
unsigned int *pint = NULL;
cout << "&a = " << &a << endl;
cout << " &pint = " << &pint << endl;
}
Output:
&a = 0x6ffe04
&pint = 0x6ffdf8
I'm wondering why the address of pint equals 0x6ffdf8. pint is an unsigned int (4 bytes), shouldn't the address of it be 0x6ffe00?
Your pint is not an unsigned int. It is a pointer to an unsigned int.
Pointer can have a different size and can especially have the size 8.
It could hence fit into 0x6ffdfc before 0x6ffe04.
But it also has bigger alignment needs, it wants an address dividable by 8, so 0x...c is out, it needs e.g. 0x...8.
With 463035818_is_not_a_number I agree that this not really predictable, there are implementation specific aspects. That is why I phrase "softly" with "can", "wants", "e.g."....
Related
This question already has answers here:
cout not printing unsigned char
(5 answers)
Closed 6 years ago.
I need to take a peek at what's inside a declared unsigned char pointer, I reduced my problem to this short example
#include<iostream>
int main (int argc, char *argv[])
{
unsigned char * buffer = new unsigned char;
*buffer = 8;
std::cout << "buffer = " << (unsigned char) (*buffer) << std::endl;
}
I am expecting this output : buffer = 8
But I get
buffer =
Blank, which drives me nuts, not even any value !!!
How I am actually dealing with it :
#include<iostream>
typedef unsigned char uint8_t;
int main (int argc, char *argv[])
{
uint8_t * buffer = new uint8_t ;
*buffer = 8;
std::cout << "buffer = " << (int) (*buffer) << std::endl;
}
I am using this example in ns3 , buffer constructs a one byte payload packet, and I need it to be a pointer.
That's why I actually tagged my question as "C" along with "C++", because the core of the issue is also concerned in C. But I found myself down voted for that ! I know "cout" and "new" are c++ literals, but it's irrelevant to the issue !!
Not having a coding problem with all that, my problem is just what's unsigned char then if it reads as a regular char with cout !!!!!
I stated I am expecting it to be buffer = 8 because unsigned char are one byte integers.
Thank you guys because you made me notice cout is dealing with it as if it is a regular char, despite it was expected for me otherwise.
If we extend your example slightly to this:
int main(int argc, char *argv[]) {
unsigned char * buffer = new unsigned char;
*buffer = 8;
std::cout << "buffer = [" << (*buffer) << "]\n";
}
the output is
buffer = ]
The ASCII char 8 means backspace, and it has nuked the opening [.
Notice you don't need the cast to unsigned char - *buffer is an unsigned char.
If you want it to have the character '8' you need to set its contents to 8.
Don't forget to delete what you new.
int main(int argc, char *argv[]) {
unsigned char * buffer = new unsigned char;
*buffer = '8'; //<---- see the single quotes?
std::cout << "buffer = [" << (*buffer) << "]\n";
delete buffer;
}
with output
buffer = [8]
Of course, we don't really need these pointers:
int main(int argc, char *argv[]) {
unsigned char buffer = '8';
std::cout << "buffer = [" << buffer << "]\n";
}
And if you insist on using raw character codes:
int main(int argc, char *argv[]) {
unsigned char buffer = 56;
std::cout << "buffer = [" << buffer << "]\n";
}
Edit:
If what you want to know is what numeric value is in the buffer variable and therefore want << to report an integer value rather than stream this as a character, use a cast.
int main(int argc, char *argv[]) {
unsigned char buffer = 56;
std::cout << "buffer = [" <<static_cast<unsigned int>(buffer) << "]\n";
}
'8' is the character 8.
8 is just a code of a character which is invisible.
Try writing *buffer = 48; and guess why the output is "Buffer = 0" based on this table.
Found this just now unsigned():
#include<iostream>
int main (int argc, char *argv[])
{
unsigned char * buffer = new unsigned char;
*buffer = 8;
std::cout << "buffer = " << unsigned(*buffer) << std::endl;
}
it gives the output I wanted in my question buffer = 8
which is not buffer = '8' as some might have thought I meant
When I run the following code:
int i[] = {1,2,3};
int* pointer = i;
cout << i << endl;
char c[] = {'a','b','c','\0'};
char* ptr = c;
cout << ptr << endl;
I get this output:
0x28ff1c
abc
Why does the int pointer return the address while the char pointer returns the actual content of the array?
This is due to overload of << operator. For char * it interprets it as null terminated C string. For int pointer, you just get the address.
The operator
cout <<
is overload 'char *' so it knows how to handle it (in this case, printing all chars till the end one).
But for int is not, so it just prints out the 'memory address'
A pointer to char is the same type as a string literal. So for the sake of simplicity, cout will print the content of the char array as if it was a string. So when you are doing this:
cout << "Some text" << endl;
It does not print the address, the same way as your code is doing.
If you want to pring the address, cast it to size_t
cout << reinterpret_cast<size_t>(ptr) << endl;
I have an array that I want to store the address of the next array in the current position.
So far I have
char *a = new char[50];
char *free = a;
*a = &(a + 1); //value of a[0] is equal to the address of a[1]
Also I'm using a char array so I'm sure I'll need to cast some stuff.
Any help would be nice.
You can't store a char* in a char array.
A character is equal to one byte. The size of a pointer, such as char*, varies depending on your computer. On my computer, its 8 bytes. 8 bytes can't fit in 1 byte.
#include <iostream>
int main()
{
std::cout << "sizeof(char): " << sizeof(char) << std::endl;
std::cout << "sizeof(char*): " << sizeof(char*) << std::endl;
return 0;
}
// Outputs
// sizeof(char): 1
// sizeof(char*): 8
You also won't be able to cast a char* to a char to fit it in the array either, as your compiler will yell at you.
#include <iostream>
int main()
{
char myArray[10];
std::cout << (char)&myArray[0];
}
// Compiler error:
// g++ main.cpp -std=gnu++11
// main.cpp: In function ‘int main()’:
// main.cpp:7:34: error: cast from ‘char*’ to ‘char’ loses precision [-fpermissive]
The closest thing you can do to get this working is to use an array of size_t. size_t is the size of a pointer. So the number of bytes in size_t and size_t* is equal, and therefore you can put a size_t* in an array of size_t... after casting.
#include <iostream>
int main()
{
size_t myArray[10];
myArray[0] = reinterpret_cast<size_t>(&myArray[1]);
std::cout << std::hex << "0x" << myArray[0] << std::endl;
}
// Outputs: 0x7fff4eded5c8
Also, consider using indicies[] instead of pointer addition. Its more readable, and it does the same thing under the hood. a[1] == *(a+1).
Why does the following code print 0? i.e. why does variable a is located right after variable d, even though pointer variable c is being declared between them?
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = &d - c;
int &f = e;
e ++;
cout << e << " " << endl;
return 0;
}
Working backwards:
e ++;
cout << e << " " << endl;
If this prints 0, then the value of e before executing this code must have been -1.
int e = &d - c;
So the result of the above address subtraction must have been -1.
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b is a reference to a, so &b is equivalent to &a.
So &d - c is equivalent to &d - &a, and that subtraction yields -1.
Conclusion: the address of d is sizeof (unsigned int) bytes after the address of a. (Pointer subtraction is scaled by the size of the pointed-to type.)
Probably.
In fact, the behavior of subtracting pointers to two independently defined objects is undefined. The standard says literally nothing about what it should do.
In practice, a compiler will probably generate the simplest possible code for a pointer subtraction, and that simple code will probably treat unrelated pointers as if they were comparable, even though the language doesn't say they are.
It's likely, given your program's output, that b and d happen to be allocated next to each other. Nothing says that declared variables have to be allocated in the order in which you declare them. If you want objects to be allocated in memory in a define order, put them into a struct or make them elements of an array.
It's also likely that the same program will yield different results if you run it on a different system, or on the same system with a different compiler, or on the same system with the same compiler with different compiler options. In principle, it could even behave differently with everything the same but during a different phase of the moon.
And a compiler is permitted to assume that your code's behavior is well defined, and perform transformations that are valid only given that assumption. In effect, by subtracting two unrelated pointers, you have promised the compiler that they both point to elements of the same array object or just past the end of it (where a single object is treated as a 1-element array) (or that both are null pointers; that's one difference between C and C++). You have lied to the compiler, which means it is under no further obligation to you.
Don't do that.
Unless you explicitly place objects using your own memory management system, their relative positions in memory will be compiler- and system-dependent.
your line int e = &d - c; is substracting 2 unsigned int *.
In memory, &d is 8 bytes farther then c (it depend on your system, but we suppose that an int is 4 bytes). Effectively, you construct your stack in this way :
unsigned int a = 100; // &a is 0x0
unsigned int &b = a; // &b is 0x0 (it's just an alias)
unsigned int *c = &b; // &c is 0x4
unsigned int d = (unsigned int)(c); // &d is 0x8
An unsigned int use 4 bytes in memory.
So, when your are doing &d - c, it must return 2, because your are using pointer arithmetics with unsigned int* (4*2=8);
You can try with int e = (short*)&d - (short*)c result should be 4 because short size is 2 (2*4=8).
You can try with int e = (char*)&d - (char*)c result should be 8 because char size is 1 (1*8=8).
Try to print your variables and addresses to understand :
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = (short*)&d - (short*)c;
//int &f = e;
//e ++;
cout << "&a: " << (unsigned int)&a << endl;
cout << "&b: " << (unsigned int)&b << endl;
cout << "&c: " << (unsigned int)&c << endl;
cout << "&d: " << (unsigned int)&d << endl;
cout << endl;
cout << " a: " << a << endl;
cout << " b: " << b << endl;
cout << " c: " << (unsigned int)c << endl;
cout << " d: " << d << endl;
cout << endl;
cout << " e: " << e << endl;
return 0;
}
Here, with int e = (short*)&d - (short*)c;, result is :
&a: 3220197356
&b: 3220197356
&c: 3220197360
&d: 3220197364
a: 100
b: 100
c: 3220197356
d: 3220197356
e: 4
I'm having troubles understanding pointer arithmetic or how memory is assigned. In the code snippet below, I am trying to access the value of 'size = 1' which is located 8 bytes before 'test', but I don't get size's value and the value is not random. So I may have an issue with understanding bytes sizes. If void*, long, and char are 8 bytes should it matter when using pointer arithmetic?
#include <iostream>
using namespace std;
char arrayOfCrap[100];
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[29]);
}
int main(){
long * test;
test = (long*)what();
*test = 1221;
cout << "Value of test: " << *test << endl;
cout << "Long number before test: " << *(test-1) << endl;
}
The code works when main moves forward from what()'s void* 'pointer:
#include <iostream>
using namespace std;
char arrayOfCrap[100];
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[28]); //change from above
}
int main(){
long * test;
test = (long*)what();
test++; //change from above
*test = 1221;
cout << "Value of test: " << *test << endl;
cout << "Long number before test: " << *(test-1) << endl;
}
Your code is not locating *size eight bytes before *test:
size = (long*)&arrayOfCrap[28];
arrayOfCrap is char arrayOfCrap[100] so arrayOfCrap[28] is the char at offset 28 and arrayOfCrap[29] is the char at offset 29.
The reason test++ works is that test is of type long*, so incrementing it actually moves to the next position for a long, whereas incrementing a char* or using an index on a char array gives you the next position for a char.
You could also do one of these:
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return size+1;
}
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[28 + sizeof(long)];
}
By the way, its not necessarily safe to take a pointer to just any memory location and treat it as a pointer to another type. Some platforms require some types to be 'aligned', or to have those types exist only at addresses that are multiples of a certain value. On those platforms reading or writing to an unaligned object may crash (bus error) or otherwise have undefined behavior. Also, some platforms may not crash or behave incorrectly, but have much better performance when reading/writing aligned objects. I know this is completely beside the point of your experimentation, but it's something you should know for real code. Here's an example of what not to do in real code:
int read_int(char *&c) {
int out = *(int*)c; // c may not be properly aligned!
c += sizeof(int);
return out;
}
Unfortunately on a common platform, x86, unaligned access is usually just slow rather than something that will always cause a crash, so users of that platform have to be especially careful.
When you increment a pointer, it increments not by the pointer size, but by the size of the type of the pointer. A char* pointer increments by sizeof(char), a long* pointer increments by sizeof(long)
sizeof(char *), sizeof(long *) should be both the same size (generally 4 bytes on 32-bit systems, 8 bytes on 64-bit systems).
However, sizeof(char) and sizeof(long) are not the same.
You are confusing your pointer size with the integer size.
#include <iostream>
using namespace std;
int main()
{
cout << "\n sizeof(char*) " << sizeof(char *);
cout << "\n sizeof(char) " << sizeof(char);
cout << "\n sizeof(long*) " << sizeof(long *);
cout << "\n sizeof(long) " << sizeof(long);
}
See it in action here: http://ideone.com/gBcjS