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) );
Related
Could somebody explain the difference between these two function declarations below please? As far I know, aDecay() takes a pointer as an argument and if you have an integer int a[5] you can call aDecay(a) or aDecay(&a[0] because an array decays to a pointer.
Now if I want to call pDecay() I have to use pDecay(&a).
How does pDecay force you to use the &.
void aDecay(int *p)
void pDecay(int (*p)[7])
With plain a (or its equal &a[0]) you have a pointer to a single element in the array. A single element is of type int, so a pointer to it must be int*.
If you have a pointer to the actual array, like you get with &a, you no longer have a pointer to a single int element but to the whole array. The type of the array is int[5], and a pointer to it is int(*)[5].
Also note that in neither case you pass the array by value. You pass a pointer by value.
This is not a pointer to function syntax, it's a pointer to array syntax.
In the first example p is a pointer to an array of integers. p[i] is a single int. It cannot be indexed any further.
In the second example p is a pointer to an array of seven integer arrays. p[i] is an array which can be indexed further, i.e. p[i][0] is valid.
Here is an example of using the second approach:
void fill_data(int (*p)[7], size_t n) {
for (size_t i = 0 ; i != n ; i++) {
for (size_t j = 0 ; j != 7 ; j++) {
p[i][j] = (int)(7*i+j);
}
}
}
int main() {
int data[10][7];
fill_data(data, 10);
}
Demo
aDecay takes a pointer to an int.
An array of int can decay to a pointer to the array's first element.
pDecay takes a pointer to an array of seven ints.
An array does not implicitly convert into a pointer to itself.
Passing p will convert the array p to a pointer instead of keeping it as an array (this is called array decay, because the array decays to a pointer).
Passing &p will not convert p to a pointer, because it will convert the pointer to p to a generic pointer, which is not a big deal because it is actually a pointer.
Why we don't want to convert p to a pointer is because arrays are not just pointers. If you think that arrays are just pointers, try to compare sizeof(myArray) with sizeof(myPointer). An array embeds also its size, not only the pointer to the first element.
First of all, you have a misconception in the question: if a is an array, a is always a pointer to that array, i.e. you do pDecay(a) - NOT pDecay(&a). Now, [ ] is a dereferencing operation, so if you say a[5] - you dereference a pointer to a + 5 * bytes in memory occupied by the array's unit. Accordingly, a and &a[0] is exactly the same. a[5] and &(a + 5) is the same.
Answering your question, aDecay(int *p) takes a pointer to integer - nothing asks for an array here. int (*p)[7] is an array of 7 integers and compiler will check that's the case.
How does pDecay force you to use the &.
Because an array doesn't decay to just any pointer. It specifically decays to pointer to first element. The type of pointer to first element of an array of int (i.e. int[n]) is: pointer to int (i.e. int*).
The argument of pDecay is int (*p)[7] which is a pointer to an array of 7 int. An int* is not implicitly convertible to (int (*p)[7]; they are separate, incompatible types. Note that pDecay(&a) won't work either because the type of &a is (int (*p)[5] which is also a different type than (int (*p)[7].
pDecay doesn't force you to use & in general. You could pass an array of arrays, which would then decay to a pointer to first array, which is what pDecay accepts:
int arr[n][7];
pDecay(arr);
Could somebody explain the difference between these two function declarations below please?
int* is a pointer to an int object. int (*p)[7] is a pointer to an int[7] object i.e. an array of 7 int.
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.
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
Ok I understand the concept of pointers to pointers. But I don't know why this doesn't work.
void function(int **x)
{
*x = 10;
}
I keep getting the error:
a value of type "int" cannot be assigned to an entity of type "int*"
What am I doing wrong or what am I not understanding about pointers to pointers?
omg x_x I was confusing C with C++.
x is a pointer to a pointer so you have to dereference it twice to get to the actual object. E.g. **x = 10;
Ok I understand the concept of pointers to pointers.
Nah...
*x is an int*, so you can't assign an int to it.
The concept of pointers-to-pointers comes from C, where references aren't available. It allows reference semantics - i.e. you can change the original pointer.
In short, you need to dereference twice.
A dereference returns the thing a pointer is ponting to, so:
int n = 10; //here's an int called n
int* pInt = &n; //pInt points to n (an int)
int** ppInt = &pInt //ppInt points to pInt (a pointer)
cout << ppInt; //the memory address of the pointer pInt (since ppInt is pointing to it)
cout << *ppInt; //the content of what ppInt is pointing to (another memory address, since ppInt is pointing to another pointer
cout << *pInt; //the content of what pInt is pointing to (10)
cout << **ppInt; //the content of what the content of ppInt is pointing to (10)
x is pointing to a type of int *, not int. You either want to do static int i = 10; *x = &i or **x = 10.
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