While experimenting with pointers, I had the idea to change the address a pointer. I tried the following:
int* pointer;
&pointer = 0x28ff0d; //To point to an empty space in memory
But that threw out an error (Details: (here) in line 2, lvalue required as left operand [...]), so I guess it's impossible? I'm not trying to make a nullpointer, but litterally to change the memory address
For obvious reasons, setting a pointer to a hardcoded address is a bad idea. But, you can do so by reinterpret_cast<>ing the address to the type you're assigning it to, like so:
int * pointer = reinterpret_cast<int *>(0xDEADBEEF);
or
int * pointer = &some_int;
. . .
pointer = reinterpret_cast<int *>(0xDEADBEEF);
Note that dereferencing pointer in this case is undefined behavior... but doing this might still be useful for something like debugging a use-after-free, where a sentinel value like 0xDEADBEEF would clearly communicate that you had already freed that memory.
Obviously the much more common, useful, and safe case for changing the address you are pointing to would be to take the address of a different (real) piece of data:
int * pointer = &some_int;
int new_val = 1234;
pointer = &new_val; // *pointer is now 1234
You can never change the address of a variable. So whatever T is (be it an intrinsic type like int or double, a struct, a pointer or an array, the following is forbidden in C++:
T var;
&var = anything; // WRONG! &var is not a lvalue
The error lvalue required as left operand means that you can only assign to something that can receive a new value, and the address of a variable is not.
A pointer is a variable. Any variable has an address where it's located. So if you've declared a varible like e.g. int x;, then &x is the address where that variable resides.
A pointer is a variable which resides somewhere, but in addition it has a value, which happens to be an address of some other variable. So if you've declared a pointer int* x;, have written something to it, then x will represent some address you've written to it, and *x will be the value pointed to by the pointer.
So your syntactic mistake was using & where you should have just used the variable name, without &. After this is clear, be sure to read the other answers which explain further problems with your code.
int* pointer;
&pointer = 0x28ff0d;
This will throw error because &pointer is not an lvalue. On the left side of the assignment operator there must be an lvalue.
Related
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.
I understand the fact that we can't assign the address literal to a pointer variable directly, thus the address of operator(&) doesn't return an address of variable/operand as literal.
int* ptr{ 0x7ffd78ad698c }; // Compiler error
Instead, it returns a pointer containing the address of the variable/operand, and then our pointer variable somehow manages to get only the address from the pointer containing an address returned by the address of operator(&).
How does the pointer variable only get address from the pointer containing an address returned by address of operator(&)? What is the lifetime/scope of the pointer returned by address of operator(&)? Is it get destroyed immediately after the pointer variable takes the address it contains?
You seem to be confused about pointers.
First, the only reason you can't do
int* ptr{ 0x7ffd78ad698c }; // Compiler error
is because the compiler thinks it's silly and a mistake. If you add a cast, the compiler will absolutely let you do this.
int* ptr{ (int*)0x7ffd78ad698c }; // Compiles
(I'll also point out that most people would write this statement using =)
Second. Pointers don't have lifetimes. Well, ptr is a variable so it has a lifetime, but the address stored in ptr doesn't have a lifetime. The thing it points to is a variable which has a lifetime. But the address itself - the number 0x7ffd78ad698c - does not have a lifetime. Your question: "What is the lifetime/scope of the pointer returned by &?" is like asking "What is the lifetime/scope of the number returned by +?"
Beware that when people say "pointer", sometimes they mean a pointer variable (which has a lifetime/scope because it's a variable), and sometimes they mean an address (which doesn't because it's not).
address literal
There is no such thing as address literal in C++.
0x7ffd78ad698c
This is an integer literal.
What is the lifetime/scope of the pointer returned by address of operator(&)?
Assuming it is applied to a pointer, the result is a prvalue.
An overloaded operator& results in whatever the overloading function returns. Overloading the unary operator& is very rare.
I'm reading a book and I have doubts about what each of these syntax does. The first three lines I can understand but the following do not. Thank you very much if you help me, Julieta
int m; //m is int variable
int *p; //Pointer p pointing to an integer value
p=&m //The memory address of the variable m is assigned to p
float *longitud;
longitud=&cable1;
*longitud=40.5;
The concepts of value, pointer, and reference often trip people up, especially as they are often taught to look at them in terms of implementation and not in terms of the language.
A value is a thing that exists and has meaning. It always has a type (a constraint on its meaning) like int, float, char, and vector<string>.
An object is a value that exists somewhere in memory. (And not, say, mangled into a machine instruction code or produced on-the-fly in some way. That is, I could take out my memory chip and stick my finger on it, were my fingers nimble enough.)
A reference is an alias — a name for an object. The name is convenient for us as programmers. How the compiler maintains that name does not really matter. All that matters (language perspective!) is that if you have a name, you have direct access to an object.
To put that into perspective, whenever you name an object, you obtain a direct reference to that object. You can manipulate that object directly using its name.
A pointer is a value. Its type is a location in the computer’s memory of some object. With this location, I can gain access to the object’s value. In other words, I can use a pointer to gain a direct reference to an object.
Vocabulary + time = fickle understandings and encourage people to ask useless things2. Let’s clean our minds up a little.
First, a pointer is not a reference, it is an indirect reference. In order to get an actual, or direct, reference to a pointed-to object, we “dereference” the pointer. In other words, we perform a magic that transforms a pointer value to obtain a reference to an object.
The mechanics of how a pointer works are typically framed in terms of how the underlying hardware does something like “follows a pointer to a value”. We draw pictures with arrows and everything. We seem to forget to ask how this magic works. No one asks how variable names work either, but it is the exact same kind of magic. We simply trust when told “the compiler takes care of it”.
What is missed is the distinction between a (direct) reference (an alias or name for an object) and an indirect reference (a pointer or other thing that can be used to obtain a reference to an object).
Before C++ the difference between direct and indirect references really only made sense in the context of a pointer, and it was easy to call a pointer “a reference” instead of the full phrase “an indirect reference”, and so the vocabulary words mixed around in our heads, and we began to misunderstand the actual concepts involved.
Enter C++, stage left. We now have things called “references” in addition to pointers. In terms of the language, they are true aliases for other objects1.
To put it to example:
int x = 7; // "x" is a reference to the integer object with value 7
int& y = x; // "y" is a reference to the same integer object as "x".
int* p = // "p" is a pointer object whose value is an
// indirect reference to some integer object:
&x; // The & operator obtains an indirect reference (or pointer value) to "x"
And here is the last point. There are more than one meaning for "&"!
When attached to a type, it means that the type is a direct reference to some object
When attached to an object, it means that an indirect reference to that object is obtained
1 In C++, the abstraction leaks, because the lifetime of an object is bound only to the original reference. But that’s neither here nor there. There are other topics that deal with that here at SO.
2 So, to answer everyone’s favorite question: is a reference a pointer or not? The answer is, it doesn’t matter. (Unless you are writing a compiler.) You are asking implementation details about magic used to maintain a language-level concept. So sometimes it may be an actual pointer, sometimes it may simply be another entry in the compiler’s local symbol table, and it may even be something else if the compiler writer thinks it useful and appropriate.
3Language gets to be fuzzy. I had previously said "p" is a pointer. Technically, it is an object whose value is a pointer type. We can usually get away by just saying what type of thing an object is, though, and be well-understood. It is only when we are splitting hairs (in context) that the vocabulary needs more care, as it does here.
longitude is a pointer to a float variable
longitud=&cable1 assigns the address of cable1 (presumably a float?) to longitud, which now references cable1.
*longitud=40.5 dereferences longitude and assign it value 40.5. Because longitud references cable1, this assigns the value to cable1. That is *longitud and cable1 are the same thing.
None of this really relates to the question title "Difference between pointer declaration and indirection" - indirection is a general computing concept, and pointers are the means by which indirection is effected in C and C++.
Suppose you add one more (different) line in each section:
int m; // m is int variable
int *p; // pointer p is pointing to an integer value
p = &m; // the memory address of m is assigned to p
*p = 42; // ADDED: assign 42 to m, where p points to
float cable1; // ADDED: the variable where longitud points
float *longitud; // pointer longitud is pointing to a float value
longitud = &cable1; // the memory address of cable1 is assigned to longitud
*longitud = 40.5f; // assign 40.5 to cable1, where longitud points to
This completes the similar examples, which use different variable types.
After executing the lines
float cable1; // ADDED: the variable where longitud points
float *longitud; // pointer longitud is pointing to a float value
longitud = &cable1; // the memory address of cable1 is assigned to longitud
the following conditions are true:
longitude == &cable1
*longitude == cable1
IOW, the expression *longitud is equivalent to the expression cable1. So when you write
*longitud = 40.5f;
this is equivalent to writing
cable1 = 40.5f;
The * operator dereferences the longitud pointer, such that the expression *longitud evaluates to the same thing as cable1.
Cable1 needs to have a place memory before longitud can point to it.
The first 3 lines do this:
Set aside memory for an int.
Create an int pointer.
Get the int pointer to point at the int's memory address. Pointer references int.
The second 3 lines do this:
Create a float pointer.
Get the float pointer to point to a nonexistent address.
Try to assign a float value to that address.
If on line 4 you wrote:
float cable1;
You would have set aside memory and everything would work fine.
On the topic, you mean pointer declaration and dereferencing. I can give a short set of examples, though it mostly takes reading and practice to learn. Try these out and get a feel.
float f = 22.2f; //sets aside memory for a float with the name "f", stores 22.2
float *pf; //declares a float pointer.
pf = &f; //sets pf to point to f's memory address. pf references p.
printf("%f", *pf); //prints the value at the referenced address (22.2)
printf("%x", pf); //prints the memory address of the pointer itself
*pf = 33.3f; //changes the value at f's address to 33.3 (from 22.2)
f = 44.4f; //changes the value at f's address to 44.4 (from 33.3)
float *pf2;
*pf2 = 33.3 //BAD. pf2 is not assigned to an address, no value to change.
*pf2 = f; //BAD. pf2 has no memory address to copy the value to.
*pf2 = pf; //BAD. several reasons.
pf2 = pf; //pf2 now points to f's address, too.
pf2 = &f; //redundant. Same as the last line.
*pf2 = 55.5 //f has changed to 55.5. both pf2 and pf point to it.
Just think of the * as standing for "pointer" when you declare. When you use * later, it means "dereference." Dereferencing a pointer means you want to look at/use/change the referenced value. Later on, you'll learn that pointers can point to other pointers. So the value of a (char **) type is type (char *), rather than type (char).
If you don't have a book, I recommend C Programming - A Modern Approach 2nd Edition. It's a little dated but an excellent way to learn the fundamentals.
I am learning about pointers in C++ and I have read an article on it and I think I understand it, though I just wanted some clarification on the pseudo code I wrote.
int someGameHealthAddress = 1693;
int healthIWantItToBe = 20;
int * newHealthValue;
newHealthValue = someGameHealthAddress;
*newHealthValue = healthIWantItToBe;
So is the above right? Like the way it works?
EDIT: Thank you all for answering, glad I got this down now. You've been a large help :)
EDIT2: I'm quite proud I've got the hang of this now. By the looks of it a lot of people have trouble understanding pointers.
If someGameHealthAddress is supposed to be an address then you need to declare it as such. E.g:
int someGameHealth = 1693;
int healthIWantItToBe = 20;
int * someGameHealthAddress; //this is the pointer to an int, which is basically its address
someGameHealthAddress = &someGameHealth; // take address of someGameHealth
*someGameHealthAddress = healthIWantItToBe; // modify the value it points to
In your code this line was wrong:
newHealthValue = someGameHealthAddress;
Because it missmatches the types of variables, it's like int* = int.
Note, that this is possible to cast from and integer type to pointer type, it's almost always a bug, because you nearly never know the absolute value of variable's address in memory. You usually locate something, and then work with relative offsets. This is usually the case when you are doing some in-memory hacking, which your example seems to be.
Almost. In order to get a pointer to a variable, you need the "address of" operator &:
// Set newHealthValue to point to someGameHealth
newHealthValue = &someGameHealth;
(I removed "Address" from the variable name, since it isn't an address. The pointer now contains its address).
Then your final line of code will change the value of the object that newHealthValue points to, i.e. it will change someGameHealth.
This statement is wrong:
newHealthValue = someGameHealthAddress;
Because the left side has type pointer and right side is an integer. You have to make sure types match in assignments. To get the address of the someGameHealthAddress, use &:
newHealthValue = &someGameHealthAddress;
Now the types match because the right side is an address of integer, and thus a pointer.
Depending if you want the value of the pointer to be 1693, or you want the pointer to point to the address of the variable someGameHealthAddress
1.assigns newHealthValue value to someGameHealthAddress value
*newHealthValue = someGameHealthAddress;
assigns the newHealthValue to point to the address of the someGameHealthAddress variable
*newHealthValue = &someGameHealthAddress;
assigns the address of newHealthValue to the value of the someGameHealthAddress variable
&newHealthValue = someGameHealthAddress;
assigns the address of the newHealthValue to the address of the someGameHealthAddress variable
&newHealthValue = &someGameHealthAddress;
* and & are two operators used in c++
& means "the address off"
ie, &p means address of p .
* means "value in the location"
*p means value in the address stored in p.
For that p must me a pointer.(because p should keep an address).
Here newHealthValue = someGameHealthAddress; will give compilation error.because someGameHealthAddress is an integer and newHealthValue is integer pointer.
int*=int is type miss-match
You can store the address of someGameHealthAddress using the following statement
newHealthValue = &someGameHealthAddress;
which means newHealthValue = (address of)someGameHealthAddress
*newHealthValue = healthIWantItToBe; is syntactically correct because it stores the value of healthIWantItToBe to the address pointed by newHealthValue
if I have a function like that:
void doSomething(int& aVar)
{
// do something
}
and I have this:
int *aVar = new int;
*aVar = 10;
doSomething(*aVar);
Why should I call *aVar? isn't aVar already an address?
No, a reference is not a pointer. References are guaranteed to not be null; you cannot say the same for a pointer. When you pass an int to a function that expects an int& the reference will be taken automatically.
P.S. Don't think of it as an address or a fancy pointer. It is a reference, or an alias to an existing object.
doSomething(int&)
wants a reference not a pointer. The way to set up that reference as a parameter is to pass in an Int. Which is why
doSomething(*aVar)
works. If you want to use a pointer in the function say
doSomething(int*)
references and pointers are not the same thing (although they have a lot in common)
The asterisk, besides multiplication has two meanings:
a) When declaring a variable: *x means "X is a pointer"
b) When using a variable: *x (when x is of pointer type) means "take whatever is pointed by x" - the opposite of &x, which means "take the address of x".
The code:
doSomething(*aVar)
just wants to dereference the pointer "aVar" (take the value of type int pointed by it) and pass this value of type int as a parameter to the function.
The variable "aVar" stores an address of some integer value, not the value itself, so you have to use the "*" operator to dereference it every time you want to access the integer, not the memory address itself.
References in C++ are quite counter-intuitive ("disguised pointers"), so if doSomething takes a reference to int, you have to call it as if you were passing an actual int value, not a pointer. Hence you need the dereference operator.
A pointer is pointing to a specific memory address and a pointer has it's own data (ie the memory address it's pointing to). When you pass aVar to the function without dereferencing (the * operator) the pointer you would be passing the memory location of the pointer, not the memory location the pointer is pointing to.