For example why would one need char **myVariable;? If a pointer is just an address in memory why what difference does it make if it's a pointer to an address with a pointer to an address of a char than just a pointer to an address with a char?
In assembly wouldn't this be like
LDR R3, =myVariable
LDR R2, =[R3]
LDR R1, =[R2]
LDR R0, =[R1]
Where a single pointer would be
LDR R1, =myVariable
LDR R0, =[R1]
now R0 holds the value? Obviously this way is faster.
In case you want to modify the value of pointer by a function, you will have to pass the address of that pointer to function by reference. Therefore you will need pointer to a pointer as argument.
Example :
int main()
{
int num=0;
int *p = #
// This function passes the pointer by value.
//So when function returns, *p points to same place
fn(p);
// This function will actually change where the pointer points to as
// it was passed by reference
fn2(&p);
}
void fn(int *ptr)
{
static int i=1;
ptr = &i;
}
void fn2(int **ptr)
{
static int j=1;
*ptr = &j;
}
Well, if you have a table of pointers, a pointer to that table would have the type "pointer to pointer".
int main ( int argc, char **argv )
an array of strings.
of course it is slower, you have the extra step in the middle, but without that extra step you cant have an array/table/list of pointers. You just have one.
Replies above have address the first part of your question. Answer to second part
"what difference does it make if it's a pointer to an address with a pointer to an address of a char than just a pointer to an address with a char?"
Though in terms of memory layout, what you are saying is right, C/C++ handles the pointer depending on its type.
When you do pointer++, it increments the pointer by size of the data-type it is pointing to.
if it is a pointer to an integer it will be incremented by 4, if it is a pointer to character it will be incremented by 1, if it is a pointer to a structure of size 20, it will be incremented by 20.
Pointer to a pointer is required when you want deal with storing pointer and dealing with it; e.g. to change the content of the underlying pointer. For example:
int i = 0, j = 1;
int* p = &i;
int** pp = &p;
Now you want to make p point to j instead of i, then you can do as:
*pp = &j; // equivalent to `p = &j;`
This is just for explanation. In real world this is required when you are dealing with functions.
void Destroy (int** pp) { // for any int pointer
delete[] pp; // deallocate the memory
*pp = 0; // set the pointer to 0, so that it's not dangling
}
And use it as:
int* pi = new int[30];
...
Destroy(&pi); // `pi` is now pointing to 0
But still in C++, you have superior alternative as "pointer reference". Which does mostly the same thing, but with better readability.
void Destroy (int*& p) { // for any `int` pointer
delete[] p; // destroy the memory
p = 0; // Null out the same pointer which was actually passed
}
use as:
Destroy(pi); // no need to pass address
Let's say you have a pointer and the value of the pointer matters. For example the pointer points to an element in an array. Then you call a function with that pointer, and you mean it as an input/output parameter, so the function would modify it. In this case this is possible by putting one more indirection into the game and passing the pointer of the pointer to the function, so it can change the pointer.
#Lindyracer's: array of pointers.
in some OSes if you get hold of a "global" pointer, then it uses a double indirection (usually you get it as a type defined by a typedef). The reason behind this is that if you store the double pointer, then the memory manager is free to change the pointer pointed by that double pointer, so it can move around things, and defrag, etc.
There are many more.
First, because it's semantically possible and necessary to complete the language, leaving no undefined territory as to what does this expression mean, &p where p is a pointer?
And it's also quite handy as it seems. Here's an answer from Linus Torvalds.
Using pointers to remove item from singly-linked list
Related
I am wondering one thing, I am trying to remember c++ after long working with c# :)
And one thing bugs me, and I don't know why it is happening.
Pointer should be thing, which points somewhere to memory(it's address)
And pointer of pointer is address of the pointer. Simple, right? :D
Let's take a look at this code:
#include <iostream>
int main()
{
int* TestMas = new int[10]
{
1,2,3,4,5,6,7,8,9
};
for (size_t i = 0; i < 10; i++)
{
printf("%d\t", *(TestMas+i));
}
}
For some reason, values are printed out instead of the addresses, it should be *(TestMas+i) should be address of the array pointer, but how values are printed out, and not address?
If I try to use & to dereference the pointer, I get an error xD How is it working?
TestMas is a int *, or the address of an integer. When you assign it to new int[10], you're pointing it to the first of 10 contiguous integers in memory that you guarantee belong to you.
So when you do *(TestMas + i), you're doing pointer arithmetic, and then dereferencing the new pointer. Note that the syntactic sugar for exactly this operation would be TestMas[i].
You probably meant to leave off the dereference if you just wanted the address. So just:
std::cout << TestMas + i;
TestMas is a pointer to an int, not a pointer to a pointer. Its type is int *. A pointer to a pointer to an int would be int **
TestMas + i is also a pointer to an int, pointing to the i-th element of the array. *(TestMas + i) is calling the indirection operator on that pointer, which returns the object or function pointed-to by the pointer operand, not the address.
The address is the value of (TestMas+i) itself.
You can print it with:
printf("%p\t", (TestMas+i) );
I'm new to programming and I'm trying to wrap my head around the idea of 'pointers'.
int main()
{
int x = 5;
int *pointerToInteger = & x;
cout<<pointerToInteger;
}
Why is it that when I cout << pointerToInteger; the output is a hexdecimal value, BUT when I use cout << *pointerToInteger; the output is 5 ( x=5).
* has different meaning depending on the context.
Declaration of a pointer
int* ap; // It defines ap to be a pointer to an int.
void foo(int* p); // Declares function foo.
// foo expects a pointer to an int as an argument.
Dereference a pointer in an expression.
int i = 0;
int* ap = &i; // ap points to i
*ap = 10; // Indirectly sets the value of i to 10
A multiplication operator.
int i = 10*20; // Needs no explanation.
One way to look at it, is that the variable in your source/code, say
int a=0;
Makes the 'int a' refer to a value in memory, 0. If we make a new variable, this time a (potentially smaller) "int pointer", int *, and have it point to the &a (address of a)
int*p_a=&a; //(`p_a` meaning pointer to `a` see Hungarian notation)
Hungarian notation wiki
we get p_a that points to what the value &a is. Your talking about what is at the address of a now tho, and the *p_a is a pointer to whatever is at the &a (address of a).
This has uses when you want to modify a value in memory, without creating a duplicate container.
p_a itself has a footprint in memory however (potentially smaller than a itself) and when you cout<<p_a<<endl; you will write whatever the pointer address is, not whats there. *p_a however will be &a.
p_a is normally smaller than a itself, since its just a pointer to memory and not the value itself. Does that make sense? A vector of pointers will be easier to manage than a vector of values, but they will do the same thing in many regards.
If you declare a variable of some type, then you can also declare another variable pointing to it.
For example:
int a;
int* b = &a;
So in essence, for each basic type, we also have a corresponding pointer type.
For example: short and short*.
There are two ways to "look at" variable b (that's what probably confuses most beginners):
You can consider b as a variable of type int*.
You can consider *b as a variable of type int.
Hence, some people would declare int* b, whereas others would declare int *b.
But the fact of the matter is that these two declarations are identical (the spaces are meaningless).
You can use either b as a pointer to an integer value, or *b as the actual pointed integer value.
You can get (read) the pointed value: int c = *b.
And you can set (write) the pointed value: *b = 5.
A pointer can point to any memory address, and not only to the address of some variable that you have previously declared. However, you must be careful when using pointers in order to get or set the value located at the pointed memory address.
For example:
int* a = (int*)0x8000000;
Here, we have variable a pointing to memory address 0x8000000.
If this memory address is not mapped within the memory space of your program, then any read or write operation using *a will most likely cause your program to crash, due to a memory access violation.
You can safely change the value of a, but you should be very careful changing the value of *a.
yes the asterisk * have different meanings while declaring a pointer variable and while accessing data through pointer variable. for e.g
int input = 7;
int *i_ptr = &input;/*Here * indicates that i_ptr is a pointer variable
Also address is assigned to i_ptr, not to *iptr*/
cout<<*i_ptr;/* now this * is fetch the data from assigned address */
cout<<i_ptr;/*it prints address */
for e.g if you declare like int *ptr = 7; its wrong(not an error) as pointers ptr expects valid address but you provided constant(7). upto declaration it's okay but when you go for dereferencing it like *ptr it gives problem because it doesn't know what is that data/value at 7 location. So Its always advisable to assign pointers variable with valid addresses. for e.g
int input = 7;
int *i_ptr = &input;
cout<<*i_ptr;
for example
char *ptr = "Hello"; => here * is just to inform the compiler that ptr is a pointer variable not normal one &
Hello is a char array i.e valid address, so this syntax is okay. Now you can do
if(*ptr == 'H') {
/*....*/
}
else {
/*.... */
}
General syntax of pointer declaration: data-type *pointer_name;
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before you can use it to store any variable address. The data type of pointer must be same as the variable, which the pointer is pointing.
Why is it important that a pointer variable should contain the address of a variable of the same data type?
As a pointer has nothing to do with the value of another variable, why can't an integer pointer have the address of float data type variable?
Correct form:
int a = 10 ;
int *ptr = &a ;
ERROR, type mismatch
float a;
int *ptr; ptr = &a;
Because when you increase a pointer like
ptr++;
it will point to an address that is one multiplied with the size of the data type. If you do
ptr+=2;
and the data type is occupying 4 bytes which would be the case if the pointer was declared as
float *ptr;
the pointer will increase with 8 byte positions.
Before answering that, let me ask you, if it were valid, what would you do with such a pointer?
Suppose you have (inside a function)
float a;
int *ptr; ptr = &a;
*p = 1;
++*p;
return *p;
In such a case, there is no reason at all not to just use an int variable if it's an int you want.
Suppose you have (inside a function)
float a;
int *ptr; ptr = &a;
a = 3.14;
++*p;
return a;
In this sort of object aliasing, there can be a use, but allowing constructions like this is a pain for compilers. Compilers are free to assume, and some do assume, that the modification of *p has no effect on the value of a, so still return 3.14 unmodified;
If the latter case is something you're looking for, you can use union, which both makes your code clearer to other readers, and makes your code clearer to the compiler:
union {
float f;
int i;
} u;
u.f = 3.14;
++u.i;
return u.f;
So, to answer: it's to prevent you from shooting yourself in the foot. It's not allowed because there is no way such a pointer is useful. The one case where it could be useful is actually a case where it doesn't work, and there is another language construct that does handle it, and handles it correctly.
There is also the simple matter of dereferencing the pointer.
something = *pointer;
How much data should be read when the pointer is dereferenced? The compiler must know the data type in order to perform operations on the data like fetch, add, etc.
It's a safety feature. A pointer of one type pointing to a variable of another is a recipe for disaster; it has almost no legitimate purpose and almost anything you do with it is dangerous, especially if the types are of different sizes.
You can override this feature by means of casting. If you do so, you can no longer claim that you didn't know you were doing something dangerous.
It is possible for pointers to point to any data type: that's exactly what void pointers are for. You can use a void * to point to any data type1, and then you can get the original pointer back.
float f = 1.0f;
int i = 12;
void *p = &f;
p = &i;
Of course, you can't dereference a void pointer without first casting it back to the correct pointer type. It is up to you to ensure that the pointer type is correct.
// In C, this is valid: implicit conversions to void * and back.
float f = 1.0f;
void *p = &f;
float *fp = p;
printf("*fp = %f\n", *fp);
// In C++, you have to use a cast:
float *fp = static_cast<float *>(p);
Void pointers have limitations: you cannot dereference them, and you cannot do any pointer arithmetic.
1: Function pointers should not be cast to void *.
Lets understand it with an example.
int main()
{
char i = 8;
int *ptr = &i;
printf("Value of i = %d", *ptr);
return 0;
}
Ans: It will print some garbage because it dereferenced 4 byte in memory.
so if you do char *ptr = &i;, it will dereference 1 byte and so on..
It will give correct answer.
I'm currently learning c language, and I bumped into this code. ptr is already a pointer type of variable, so what is the effect of the & operator on it, cause I know that usually the operator uses to get the address of non-pointer variable.
struct name {
int a; float b; char c[30];
};
int main()
{
struct name *ptr;
int i,n;
printf("Enter n: ");
scanf("%d",&n);
ptr = (struct name*)malloc(n*sizeof(struct name));
/* Above statement allocates the memory for n structures with pointer ptr pointing to base address */
for(i=0; i<n; ++i) {
printf("Enter string, integer and floating number respectively:\n");
scanf("%s%d%f", &(ptr+i)->c, &(ptr+i)->a, &(ptr+i)->b);
}
}
&(ptr + i)->c
this takes the address of the variable c stored at the ith element of ptr. So your first intuition was correct.
ptr+i
is simply the pointer arithmatic to find the ith element fo the array.
(ptr+i)->c
accesses the field c from that struct, and the & takes the address of that variable.
The code &(ptr + i)->c gives you the address of the struct element c that belongs to the ith struct in your list. Let's break it down a bit.
(ptr + i) is pointer arithmetic. It adds i to the address stored at ptr.
(ptr + i)->c accesses the struct element c through the pointer (ptr + i).
&(ptr + i)->c takes the address of the struct element c through the pointer (ptr + i).
Also, I know this isn't quite doing what you thought it was doing, since you thought the address-of operator applied to the pointer, but just an FYI: you can indeed take the address of a pointer. Such a construct is a pointer to a pointer, and is useful when you want to change the pointer (not just the value stored at the address it points to) in a function. e.g.
int a = 5; /* regular variable */
int* pa = &a; /* pointer to a */
int** ppa = &pa; /* pointer to pointer (which points to a) */
Firstly, operator & in C and C++ languages is used to get address of any variable. More precisely, it can be used to get address of [almost] any lvalue (there are some differences between C and C++ in that regard). Pointer variables are ordinary variables. There's nothing special about them, which means that there's nothing unusual in seeing operator & applied to pointers.
Secondly, in the code you provided, there actually isn't a single instance of & being applied to a pointer. There are four applications of & in your code
&n
&(ptr+i)->a
&(ptr+i)->b
&(ptr+i)->c
In the first two cases it is applied to int objects. In the thirds case it is applied to float object. In that last case it is applied to a char [30] object. No pointers.
struct name* ptr;
This creates a pointer to a name.
struct name** p = &ptr;
This creates a pointer to a pointer to a name by taking the address of the pointer you already created.
In your case, you are passing in pointers to scanf, and have a dynamic array of name, so
&(ptr + i)->c
finds the ith element of the array, and returns the address of its c member to scanf (same with a and b).
Passing in the address of the pointer allows for that pointer to be changed (e.g. reallocated). In C++, it would be virtually identical to passing by reference.
What does it mean when an object has two asterisks at the beginning?
**variable
In a declaration, it means it's a pointer to a pointer:
int **x; // declare x as a pointer to a pointer to an int
When using it, it deferences it twice:
int x = 1;
int *y = &x; // declare y as a pointer to x
int **z = &y; // declare z as a pointer to y
**z = 2; // sets the thing pointed to (the thing pointed to by z) to 2
// i.e., sets x to 2
It is pointer to pointer.
For more details you can check: Pointer to pointer
It can be good, for example, for dynamically allocating multidimensional arrays:
Like:
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
if(array == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
It means that the variable is a pointer to a pointer.
Pointer to a pointer when declaring the variable.
Double pointer de-reference when used outside the declaration.
Pointer to a pointer.
You can use cdecl to explain C-types.
There's an online interface here: http://cdecl.org/. Enter "int **x" into the text field and check the result.
**variable is double dereference. If variable is an address of an address, the resulting expression will be the lvalue at the address stored in *variable.
It can mean different things if it's a part of declaration:
type **variable would mean, on the other hand, a pointer to a pointer, that is, a variable that can hold address of another variable, which is also a pointer, but this time to a variable of type 'type'
It means that the variable is dereferenced twice. Assume you have a pointer to a pointer to char like this:
char** variable = ...;
If you want to access the value this pointer is pointing to, you have to dereference it twice:
**variable
It is a pointer to a pointer. You can use this if you want to point to an array, or a const char * (string). Also, in Objective-C with Cocoa this is often used to point to an NSError*.
Pointer to another pointer
** is a pointer to a pointer. These are sometimes used for arrays of strings.
It's a pointer to pointer.
As in if *x means that it will contain an address of some variable then if i say
m=&x then m is shown as
int **m