If we have code:
int b = 10;
int* a = &b;
std::cout << a << " " << &a << " ";
As the result, the addresses are different.
But what's the meaning of address of a pointer?
A pointer has the value of a variable's address, since we have a varaible in memory. But we don't have the value of address stored in memory, so why we have the address of an address?
Maybe I have some misunderstandings, thank you for your help.
Remember an address on your machine is going to be, itself, a 32 or 64-bit value (depending on your system architecture).
In your example, you have the integer b that stores the value 10 in some address, let's call it address 500
Then you have a pointer a, which stores the value 500, and IT has its own address.
What's the point? You can actually have double-pointers (or more).
You understand that in
char* string = "hello";
string is a pointer to the beginning of an array of characters
Then
char** strings;
is a pointer to a char*. That's how you could do an array of arrays, for example.
std::cout << a << " " << &a<<" ";
Yes ,both are different .
1. a has been assigned address of b , so it prints address of b.
2. &a prints address of pointer a itself .
And a and b don't have same address.
It's similar(to understand) to this example -
int b=9;
If you print b you get its value i.e 9 but if you print &b you gets its address , and in no ways they will be same .
Same is the case with pointers.
A pointer has the value of a variable's address, since we have a variable in memory. But we don't have the value of address stored in memory, so why we have the address of an address?
We declare a variable (pointers , array , just int, char) these all are declared in program and are stored in memory . As these are stored in memory ,they have their unique address.
A pointer has the value of a variable's address
I assume by a variable you mean the object corresponding to the variable. Nonetheless, this is not strictly true, and it's the edgecases where we start to make distinctions between addresses and pointer values.
There are pointer values that don't point at objects at all. Consider null pointers, for example.
Addresses, by definition, do point at objects... or functions.
what's the meaning of address of a pointer?
The term address of a pointer makes sense if you can imagine a variable declared to store a pointer (e.g. T *var;) and you take the address of it (&var).
so why we have the address of an address?
An address is a type of pointer value, but pointer values don't point at values; they point at objects or functions. &a is different to a because the two pointers point at different objects; one points at a and the other points at b.
Thanks for you all I knew what's wrong with it.
In fact I created a pointer in memory by int* a = &b; but I thought I didn't so it's my mistake.
But what I thought that you cannot output the address of something that does not exist in memory like cout<<&(&a),the compiler will tell you that "&" operator need a l-value variable.
And if you want to output the address of pointer to a, you define a pointer to pointer variable int **p2p=&a, and then you can cout<<&p2p , it works.
Related
char a[] = "hello";
My understanding is that a acts like a constant pointer to a string. I know writing a++ won't work, but why?
No, it's not OK to increment an array. Although arrays are freely convertible to pointers, they are not pointers. Therefore, writing a++ will trigger an error.
However, writing
char *p = a;
p++;
is fine, becuase p is a pointer, with value equal to the location of a's initial element.
a++ is not well-formed since a decays to a pointer, and the result of the decay is not an lvalue (so there is no persistent object whose state could be "incremented").
If you want to manipulate pointers to the array, you should first create such a pointer:
char* p = a; // decayed pointer initializes p
a++; // OK
++a; // even OKer
This is a very good question actually. Before discussing this, let's back to the basic concepts.
What happens when we declare a variable ?
int a=10;
Well, we get a memory location to store the variable a. Apart from this an entry is created into Symbol table that contains the address of the variable and the name of the memory location (a in this case).
Once the entry is created, you can never change anything into the symbol table, means you can't update the address. Getting an address for a variable is not in our hand, it's done by our computer system.
Let's say, we get address 400 for our variable a.
Now computer has assigned an address for the variable a, so at a later point, we can't ask computer to change this address 400 because again, it's not in our hand, our computer system does it.
Now you have an idea about what happens when we declare a variable.let's come to our question.
Let's declare an array.
int arr[10]
So, when we declare this array, we create the entry into the symbol table and, store the address and the name of the array into the symbol table.
let's assume we get address 500 for this variable.
Let's see what happens when we want to do something like this :
arr++
when we increment arr, we want to increment 500, that is not possible and not in our hand, because it has been decided by the computer system, so we can't change it.
instead of doing this we can declare a pointer variable
int * p= &arr;
What happens in this situation is: again an entry is created into the symbol table that stores the name and the address of the pointer variable p.
So when we try to increment p by doing p++, we are not changing the value into the symbol table, instead we are changing the value of the address of the pointer variable, that we can do and we are allowed to do.
Also it's very obvious that if we will increment the a the ultimately we are going to loss the address of our array. if we loss the address of array then how will we access the array at a later point ?
It is never legal in C to assign to an expression of array type. Increment (++) involves assignment, and is thus also not legal.
What you showed at the top is a special syntax for initializing a char array variable.
I think this answer here explains "why" it's not a good idea;
It's because array is treated as a constant pointer in the function it is declared.
There is a reason for it. Array variable is supposed to point to the first element of the array or first memory instance of the block of the contiguous memory locations in which it is stored. So, if we will have the liberty to to change(increment or decrement ) the array pointer, it won't point to the first memory location of the block. Thus it will loose it's purpose.
int var = 100;
cout << (int*)var<< endl;
cout << &var<< endl;
(int*)var printed just 100 in hex, which I don't quite understand. Can you explain why it is doing so?
I would like to know other ways of pointing to an address without creating a complete new pointer variable.
What you have just written does not make sense. First you say:
int var = 100;
... but then you typecast the value of var into "a pointer to an int":
(int *)var
The only reason why it didn't crash-and-burn is that you did not actually try to use that pointer to access something in memory. But, cout was smart enough to realize, "say, the programmer says that this is a pointer." So it printed, in hex, the value of the pointer itself, not any data that the pointer was supposedly pointing at.
Just To Be Clear:
(int *)var does not mean "point to the address of a variable." (If you want "the address of something," albeit not "a pointer to the same", use &var). Instead, this is just a typecast, which in this case means: "treat the value of var as 'a pointer to an int'."
If * means pointing to the adress of a variable, then...
Does * mean "pointing to the adress of a variable" though? What do you think this means?
21 * 2
* means different things in different contexts. In a type name, it means that the type is a pointer. In an expression it is an operator. In case the operator is binary and operands are numbers, it means multiplication. In case the operator is unary and the operand is a pointer, it means indirection through that pointer.
(int*)var printed just 100 in hex, which I don't quite understand. Can you explain why is it doing so
This is how reinterpreting an integer to a pointer type typically works. The value was 100, and the value remained 100 when you reinterpreted it as a pointer.
Strictly speaking, the conversion isn't meaningfully defined for integer types that aren't large enough to represent all pointer values, so converting an int doesn't make sense.
I would like to know other ways of pointing to an adress without creating a complete new pointer variable.
You've shown a way how to do that: &var. That creates a pointer object pointing to var without creating a pointer variable. Another way to create a pointer prvalue is use this keyword in a member function, or call a function that returns a pointer.
When I do the following:
1. int y = 5;
2. int &a = y;
3. cout << &a << endl; // the address of a is the same address of y
4. cout << a << endl; // this has the value of y, which is 5.
Why does the a has the same address of y? I know that changing a will change y also.
But how do you read line 2? Do you read it as address of a contains the value of y?
Does this mean that a and y share the same physically memory location? Or are there 2 different memory locations with the same address?
In line 2, you are creating a C++ reference, not using the address of operator. The reference causes a to be roughly equivalent to y for all uses including taking its address.
Effectively the symbol a is just another name for y.
References are (broadly) just syntactic sugar for pointers, so a is really just a pointer to y wrapped up with automatic dereferencing. (There is slightly more to it than that, but for the sake of discussion we can think of it that way without getting misled about anything.) So when you ask for the address of a, you are really asking for the underlying pointer value, which has been set to be &y.
When you ask for the value of a, it automatically dereferences the pointer, so it is giving you the value which is at &y. Naturally, this value has y's value.
Does this mean that a and y share the same physically memory location?
No, there are two different memory locations. One holds an int value, the other holds a pointer to that int value.
Or are there 2 different memory locations with the same address?
Pretty much, yes. y is not holding a pointer/address value, though; it is actually holding the integer value itself. (Remember that y is stack memory, not a pointer to a heap object.)
When you take the address of a reference, you are not getting back "a pointer to that reference". You will simply get back the address of the referent itself.
Read this:
http://www.tutorialspoint.com/cplusplus/cpp_pointer_operators.htm
int &a = y;
Here in line 2, you are declaring that "Address of 'a' is equal to the address of variable 'y' ".In other words, 'y' has another name 'a'.
cout << &a << endl; // the address of a is the same address of y
I think there cannot be two memory locations with same address.
It's just that two variables refer to the same address.
Why can we do:
char* array = "String";
but not
int* array = 1;
To my understanding * means address, so I don't really understand why we can give a non-address value, like "String." to char* array.
char* array means that array is a variable that can hold the address of another object (such as another variable or constant).
If the program has "String", it means that there is actually an array of 7 characters that exists in memory somewhere and it holds the contents "String".
When you write array = "String"; then the variable array is made to hold the address of the letter 'S' in that string.
This is because C++ has a rule, sometimes called array-pointer decay which means that if you try to use an array (such as "String") in a context where a value is expected, then it gets automatically converted to a pointer to the first element of that array.
Without that rule you'd have to write array = &("String"[0]); . The rule was included in C originally to avoid having to write &....[0] all over the place when working with arrays, although in hindsight it seems to have generated more pain than pleasure.
Moving onto int* i = 1. You have said that i can hold the address of an int, but you have not provided any such address. Variables thare aren't arrays don't automatically get converted to their address. In fact 1 isn't even a variable. We call it a prvalue , it doesn't have any memory storage area associated with it, so it does not have an address. To point at an instance of a 1 you would have to make a variable, for example:
int j = 1; int* i = &j;
* does not mean adress. Its meaning is context sensitive, but most of the time it means pointer.
The reason for this, not to work is because "String" is an array of characters, or a pointer to an character. In contrast to this, 1 is a literal which is not a valid adress. You should write int array = 1 instead, and after that you could do int *brray = &array.
* means a pointer, not an address. You can retrieve an address using the & operator.
char* array = "String";
Actually declares array as a pointer to a character, and the = sign after the declaration tells the compiler what value should the pointer posses. In this case it's an address of "String" in the string pool somewhere in the memory of the run program.
int* array = 1;
Doesn't put the address of 1 to array as you may expect. However, with a little adjustment
int* array = (int*)1;
... it could point to an integer at address 1, which is unfortunately unaccessible.
This assignment:
char* array = "String";
Assign "String" to an available location in memory and returns the memory address of the first position of "String" in memory. "array" stores the address of "S".
This assignment:
int* array = 1;
Doesn't work because you are trying to assign an integer to a pointer to integer. The types are different
"I don't really understand why we can give a non-address value, like "String." "
That's because a character string literal actually is const char[] array, which decays to a pointer when assigned to a char*, while 1 isn't one and you can't take it's address in any way.
I'm teaching myself C++, and as such have been writing some example code to really nail my understanding of pointers and arrays.
I have written this:
int myints[] = {20, 40, 60, 80, 100};
// C style array? should be stored on stack? is myint's type pointer to int or an array of int? how does it differ from myotherints?
int* myotherints = new int[5]{20, 40, 60, 80, 100}; // new always returns pointer, is this a C++ style array?
// does this pointer get created on stack while the elements themselves are created in free heap?
int j = 5; // should be stored on stack
cout << "myints: " << myints << endl; // decays to pointer, shows address array myints is stored at
cout << "*myints: " << *myints << endl; // myints decays to pointer and is dereferenced to return value stored at start of array myints
cout << "myints[0]: " << myints[0] << endl; // [] dereferences and returns value for element 0 (20)
cout << "myotherints: " << myotherints << endl; // some value?? this is totally unlike the others, why? what is this?
cout << "*myotherints: " << *myotherints << endl; // dereferences pointer myotherints to get address that holds value 20 for first element
cout << "myotherints[0]: " << myotherints[0] << endl; // [] dereferences pointer to get address that holds value 20 for first element
cout << "j: " << j << endl << endl; // 5, sure
cout << "&myints: " << &myints << endl; // array behaving as pointer, gives address of myints[0]
cout << "&myints[0]: " << &myints[0] << endl; // array behaving as pointer, gives address of myints[0]
cout << "&myotherints: " << &myotherints << endl; // address of myotherints, is this where the pointer to the array is stored?
cout << "&myotherints[0]: " << &myotherints[0] << endl; // [] dereferences the pointer that myotherints points to and returns element 0
cout << "&j: " << &j << endl; // address of j
/*
myints: 0x7fff096df830 <-- this makes sense to me, array decays to pointer to give first element address
*myints: 20 <-- this makes sense to me, dereference first element address for value
myints[0]: 20 <-- [] dereferences implicitly, returns value from pointer
myotherints: 0x2308010 <-- myotherints is a pointer to an array of ints, but its address is much lower compared to myints and j, why is that?
*myotherints: 20 <-- getting the value from above address returns 20
myotherints[0]: 20 <-- [] dereferences to address pointed to by pointer myotherints, returns value
j: 5
&myints: 0x7fff096df830 <-- same as below
&myints[0]: 0x7fff096df830 <-- same as above, meaning *myints and myints[0] are the same thing, this address
&myotherints: 0x7fff096df828 <-- how can the pointer to myotherints array be stored here when dereferencing it (*) returns 20 and...
&myotherints[0]: 0x2308010 <-- dereferencing this address with [] also returns 20, yet they are different memory locations unlike myints
&j: 0x7fff096df824
*/
Is it true to say that myints is a "C style array" while myotherints is a "C++ style array"?
If I'm understanding correctly, myotherints is a pointer yet myints is an array that most of the time behaves like a pointer? So while you can do pointerish things with myints, there are times when it does not behave like a pointer, namely using & to reveal its address. This means myints is of a different type to a pointer. Is its type "array of ints"?
Where is myints (the thing that is myints, not the values in its array) stored, and how can I reveal its address if it always automatically dereferences to the location the array is stored at unlike the pointer returned with the C++ style new array?
Are these represented in memory in a functionally different way?
Any tips or directions to documentation that can really solidify my understanding here would be much appreciated. Thank you!
Both are things inherited from C (The proper C++ array thing is std::array), but you are confusing things:
The first is a C array, that is, a thing with static/automatic storage duration which represents a block of memory. The size and "position" (Address) of that block is determined at compile-time.
The second is a pointer to a dynamically allocated memory block. In other words, you use a pointer to store the address of the memory block you requested to the OS. This is confusing for novices since this thing is sometimes called dynamic array. Is not an array in the same sense a C array is, but in practice we use both in the same way, but for different purposes.
Regarding C++:
C arrays behave like pointers to the memory block with some suggar (Array indexing, etc), so they are always passed by reference (Since which we have is the address passed by value, not the array itself), and in fact they decay automatically into pointers in many situations. These issues make std::array a much better alternative, since it has correct value semantics and no implicit decaying.
In C++ manual memory management should be avoided, you should use the containers the Standard Library provides (The best well known std::vector). The C++ language provides features for automatic, deterministic, and safe resource management; memory resources included. You should use these. Manual memory management is provided only for very low-level programming and creation of your own resource management handler.
C++ got type decay from C.
In C there are few ways to usefully use an entire array. You cannot pass them to functions, return them from functions, perform [] or == or + or almost anything on them, at least directly.
Instead the array 'decays' to a pointer to its first element whenever you, well, look at it funny. (basically, whenever you use it in all but the few situations where it is treated as an actual array, it decays into a pointer).
So arr[3] becomes (&(first element of arr))[3] or *((&(first element of arr))+3) (these mean the same thing).
Similar thing happen when you return arr; or pass it to a function (in C). Your cout << arr means cout.operator<<( arr ), which is just a function. Well, it could also be operator<<( cout, arr ). In C++, you can pass a reference to an actual array to a function, but it takes a bit of work and is not happening in your example code.
If you type &arr decay does not occur, and you get a pointer to the entire array. This matters because of pointer arithmetic, among other reasons, and is how arrays-of-arrays can work with zero overhead. (&arr)+1 points to past-the-end of the array, no matter how big it is -- ((&(arr[0]))+1) points to the second element of the array.
This is how int arr[3]={4,5,6}; works, or int arr[]={4,5,6}; (same thing -- second one just determines the number 3 for you). arr in both cases is of type int[3]. It decays to int* easily, but it is of type int[3]. sizeof(arr) is three times the sizeof(int), not sizeof(int*).
When you new int[3] , you do not get a pointer to int[3], instead you get a pointer the first element of the int[3] array. In a sense, it gets pre-decayed. This is the type of the pointer -- the address of the array and first element is the same. But type information (which is a complie time concept) differs!
It is also stored on the free store, and not automatic storage (aka the heap and stack repectively). But that is not the fundamental difference.
The only thing C++ about the new int[3] was that you used new -- you can use malloc to get data space on the free store, and get a pointer to the first element as an int* in C as well.
It sounds like you have questions about pointers v arrays more than anything, Ill try and go through and hit all of your questions though,
int myints[] = {20,40,60,80,100};
C style array?
Well yes that is how you declare a C style array
is this on the stack?
Yes the entire array (all 5 variables) is located on the stack, this means that when its block goes out of scope the data itself goes out of scope as well, being "freed" by moving the stack pointer, this does not mean you cannot make a pointer to this array for use in other functions using the & operator though.
how is this different from myOtherInts?
This is a value on the stack, whereas myotherints is a value on the heap, with a pointer on the stack.
int* myOtherInts = new int[]{20,40,60,80,100};
does this pointer get created on stack while the elements themselves are created in free heap?
Yes declaring an int* means that you are declaring a pointer on the stack (the pointer not the value is created on the stack) and when you assign that variable to what the new function returns, (which should be memory allocated on the heap which must be freed later) you then have a stack stored pointer to a heap stored value.
cout << "&myotherints: " << &myotherints << endl;
address of myotherints, is this where the pointer to the array is stored?
Yes this returns the address of which location in memory holds the pointer to your actual data which is different than where your data is actually stored.
//myotherints: 0x2308010 <-- myotherints is a pointer to an array of ints, but its address is much lower compared to myints and j, why is that?
the value you are printing here is the address where your data is stored which is different than the location that pointer is stored in. The reason why this value is much lower is because this address that this memory resides on is controlled by the heap, which typically holds the lower address spaces of the program.
&myotherints: 0x7fff096df828 <-- how can the pointer to myotherints array be stored here when dereferencing it (*) returns 20 and...
&myotherints[0]: 0x2308010 <-- dereferencing this address with [] also returns 20, yet they are different memory locations unlike myints
This ones a little bit tricky. Recall that the & operator means "give me the address of" so to translate your code down to english a little bit you have
give me the address of myotherints
recall that myotherints is a pointer that you allocated on the stack, however this pointer points to memory on the heap. so you should expect to get a value that looks like it came from the stack (ie, generally a higher value)
give me the address of the first element of myotherints
now, again myotherints is a pointer to a value on the heap, and when you dereference it with [0] you get the value of your first element, which is stored on the heap, so when you ask for the address of something stored on the heap, you should expect a different result from something stored on the stack. (ie. a rather low number representing heap data)
EDIT: for the truly C++ way to allocate arrays you should probably be using std::array see Manu's answer
new operator, in fact, is a special kind of method and in a nutshell it requests operating system to give some free memory and returns address of newly allocated memory. So, it returns standard memory address. myints is a mere address in a nutshell. Memory to store it is not allocated on the stack. You can perform basic pointer algebra on it but you can't modify it's address. If you're familiar with asm, you may think of myints as a simple label. In C and C++ you can indeed define labels in your methods like this:
...
some_label:
/* some code here*/
goto some_label;
The compiler shall generate code that shall instruct processor to use some kind of jump instruction. Some jmp stack_pointer + some_label. Likewise, trying to modify myints fourth value number instructs compiler to generate call similar to previous example like "write this value on address stack_pointer + myints + 4 * sizeof(member of myints)" or something like that.