How to use "pointer to array 10 of int"? - c

I have the following code:
#include<stdio.h>
int main()
{
int(* a)[10]; //declare a as pointer to array 10 of int
int b[10]; // taken a array of 10 int
b[2]=32;
a=&b;
printf("b is on %p\n",&b);
printf("a is on %p\n",a);
printf("magic is %d\n",a[2]); // why this is not showing 32
return 0;
}
output:
b is on 0xbfa966d4
a is on 0xbfa966d4
magic is -1079417052
Here I have taken a as pointer to array 10 of int which points to the array b, so now why am I unable to get the value of 32 on a[2]?
a[2] is evaluated as *(a+2) so now a has address of array b so *(b+2) and *(a+2) are similar so why am I not getting value 32 here?
Edit :
i got answer by using
(*a)[2]
but i am not getting how it works ...
see
when
a[2] is *(a+2) and a+2 is a plus 2 * sizeof(int[10]) bytes.
this way (*a)[2] how expand?

Since a is already a pointer, you have to dereference it in order to refer to the array that it points to:
(*a)[2]

By the rules of pointer arithmetic, a[2] is *(a+2) and a+2 is a plus 2 * sizeof(int[10]) bytes.
(Think of an ordinary int *p; p+1 is p plus sizeof(int) bytes and (char *)(p + 1) is different from (char *)p + 1. Now replace int with int[10])

#include<stdio.h>
int main()
{
int(* a)[10]; //declare a as pointer to array 10 of int
int b[10]; // taken a arry of 10 int
b[2]=32;
a=&b;
printf("b is on %p\n",&b);
printf("a is on %p\n",a);
printf("magic is %p\n",a + 2); // Changed to show pointer arithmetic
return 0;
}
This prints the following:
b is on 0xbfe67114
a is on 0xbfe67114
magic is 0xbfe67164
Do you see what's going on? magic minus a equates 80, that is, 4 * 10 * 2.
This is because a is a pointer to an array of ten integers, so sizeof(*a) == 10 * sizeof(int) and not sizeof(a) == sizeof(int), which is what you was expecting to.
Pay attention to types in pointer arithmetic next time!

I was not able to add a comment here since it requires 50 reputation. So here goes my question for the question posted.
Sorry if I will be violating some of the rules by posting the question in the answer box.
This question shows that we should be careful while performing pointer arithmetic. But what is the good use of using pointers to an array if same thing could be done just by using pointers to integers ....?

int b[10] == int* that points to the first value in the array
int (*a)[10] == int** that point to the address of a pointer that points to an array
a+2 == (&b)+2
Hope this clears things up for you

Related

What is the difference between int* p and int (*p)[] in the context of arrays.?

Using DevCpp with TDM GCC 4.9.2 on Windows 8. But I don't think the platform matters for this question.
I know that we can use a pointer to point to a single data or an array of data.
I have learned about pointer to arrays but never used it. What advantage does one have over the other?
Sample Code...
#include <stdio.h>
int main()
{
int x[2]={10,20};
int *p1= NULL; //simple pointer
int (*p2)[] = NULL; //pointer to an array, specifically
p1 = x;
p2 = &x; //removing the & gives me a warning of "assignment from incompatible pointer types".
printf("x[1] = %d\n", x[1]);
*(p1+1) = 7;
printf("x[1] = %d\n", x[1]);
(*p2)[1] = 55;
printf("x[1] = %d", x[1]);
return 0;
}
Does p1 or p2 have an advantage over the other?
They are completely different.
int *p; - is the pointer to the int
int (*p)[1]; is a pointer to the array (in this case one element only)
In your trivial example the pointer arithmetic will be the same and generated code will be the same. But they still have different types and you may get warnings when compiled.
The "advantages" you will see when your example will be less trivial:
int (*p)[100];
p++; the pointer will point to the next 100 elements int array.
Pointer to an array means a pointer which accepts address of an array.
let's say array is int arr[5],in which size of int is 4 byte.
p is a pointer to an array that accept the address of an int array.
int arr[5];
int (*p)[5];
p=&arr;//address of an array block
let's say the base address is 1000 .So after increment in p it will lead us to 1020 address,because the size of the array block is 20 bytes.
p points to 1000 address
p++;
//Now p points to 1020 not 1004.
Whereas in case of int *q, q will point to 1004 as usual.

3d array print address after deference twice?

Why does a 3D array print address after being dereferenced twice? Please help me understand the code posted below, (assume that the array begins at location 1002).
int main()
{
int a[2][3][4]={
{
1,2,3,4,
4,5,6,7,
9,1,1,2
},
{
2,1,4,7,
6,7,8,9,
0,0,0,0
}
};
printf("%u %u %u %u\n",a,*a,**a,***a); //a == *a == **a, all print address 1002. Why?
}
**a has type int * and points to the first int in the 3D array
*a has type int (*)[4] and points to the first row of the 3D array
a has type int (*)[3][4] and points to the first 2D array in the 3D array
&a has type int (*)[2][3][4] and points to the whole 3D array
So they are all pointers that point to the same address. It's just that the type of the pointer is different. The following code may help illustrate this point.
int main( void )
{
int a[2][3][4]={ 1,2,3,4, 4,5,6,7, 9,1,1,2, 2,1,4,7, 6,7,8,9, 0,0,0,0 };
int *ptrInt; // pointer to an int
int (*ptrArray1)[4]; // pointer to an array of ints
int (*ptrArray2)[3][4]; // pointer to a 2D array of ints
int (*ptrArray3)[2][3][4]; // pointer to a 3D array of ints
ptrInt = **a;
ptrArray1 = *a;
ptrArray2 = a;
ptrArray3 = &a;
printf( "%p %p\n", ptrInt , ptrInt + 1 );
printf( "%p %p\n", ptrArray1, ptrArray1 + 1 );
printf( "%p %p\n", ptrArray2, ptrArray2 + 1 );
printf( "%p %p\n", ptrArray3, ptrArray3 + 1 );
}
Note: I left out the inner braces in the array initialization specifically to demonstrate that the inner braces are optional. Best practice would have all of the inner braces.
Typical output from this code is shown below. I've added comments to show the difference between the two pointers as a decimal number.
0x17b00 0x17b04 // 4 bytes, hence pointer to an int
0x17b00 0x17b10 // 16 bytes, pointer to int[4]
0x17b00 0x17b30 // 48 bytes, pointer to int[3][4]
0x17b00 0x17b60 // 96 bytes, pointer to int[2][3][4]
Note that when you add 1 to any pointer, the size of the object is added to the pointer. For example, if you have an int * and you add 1 to that pointer, the value of the pointer will increase by 4 because sizeof(int) == 4. (Yes, that assumes that ints are 32-bits, thank you.)
So by adding 1 to a pointer, you can determine the size of the object that the pointer points to. That gives you a clue about the type of the pointer from the compiler's point of view. In the example above, notice that adding 1 to ptrArray1 changes the pointer by 16. That's because ptrArray1 points to an object of size 16, specifically it points to an array of 4 ints.
Just so that we're all completely confused, allow me to say that the following line of code will print the number 8. I chose 8 since it only appears once in the array, so you can tell where it's coming from.
printf( "%d\n", ptrArray3[0][1][1][2]);
Notice that it appears that I'm using ptrArray3 as a 4-dimensional array. This is why pointers to multidimensional arrays are so confusing in C. When you convert an array to a pointer, the pointer has one less dimension than the array. But when you use the pointer with array syntax, you use it as though it had one more dimension.
So for example, start with a 2D array
int array[4][100];
The corresponding pointer is a pointer to a 1D array
int (*ptr)[100] = array;
But you can use that pointer like a 2D array
ptr[2][100] = 6;
That is the basis for all of the confusion, and the reason that pointer-to-array is a seldom used feature in C.
a has the type array of size 2 of arrays of size 3 of arrays of size 4 of int.
*a has the type array of size 3 of arrays of size 4 of int.
**a has the type array of size 4 of int.
All three arrays when decayed to corresponding pointers have the same value because they point to the same location in memory.
Try the following Code:
int main()
{
int a[2][3][4]={
{
{1,2,3,4},
{4,5,6,7},
{9,1,1,2}
},
{
{2,1,4,7},
{6,7,8,9},
{0,0,0,0}
}
};
printf("%u %u %u u%",a,*a,**a,***a);//how a == *a == **a print address 1002 please help me to understand ?
}
The reason it was returning the address was because you didn't declare your 3d array properly at all. The above is the corrected code, try it out and let us know how it goes

Printing pointer to pointer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
It prints 3 while I want to print 2. I do not understand the reason when I am incrementing only once. Also let me know if this is correct use of pointers t pointers? I just made a sample code to see how pointers to pointers work.
#include<stdio.h>
void main(){
int a1[] = {1,2,3,4,5,6};
int a2[] = {7,8,9,10,11,12};
int *a3 = a1;
int *a4 = a2;
int **a[2];
a[0] = a3;
a[1] = a4;
printf("%d",*(++(*a)));
}
You declared a as an array of int**, so *a is not a pointer to int but a pointer to pointer to int. Incrementing a pointer adds the size of the data type it points to, so ++*a advances the value at at a[0] by the size of a pointer.
What you actually stored in a[0] is a pointer to int, not a pointer to pointer to int. This is wrong and the compiler should have warned you about this. On your architecture it seems that a pointer is double the size of an int, so the increment ++*a adds the size of two ints to the pointer, so the value at a[0], if interpreted as int* instead of int **, skips over the 2.
To get the results you expect declare a as an array of int *.
int *a[2];
a[0] = &a3;
a[1] = &a4;
printf("%d",*(++(**a)));
As per definition, a is supposed to contain pointer to int pointer. So need to add & in front of a3 and a4. In printf need to use de-reference twice before incrementing for same reason.
*a = *(a + 0) = a[0] that contain address = a3 , int*(in your code a[0] = a3;).
a3 points to first element of a1 (in your code int *a3 = a1;, that is one) Hence *a point first element of of a1.
By doing ++(*a) you are pointing to next element in a1 that is at index 1 and last by using * at ++(*a) you are printing 1 indexed value in a1 array that outputs: 2 thats is a1[1]
So, *(++(*a)) actually a1[1].
You code print 2 not 3, check here your working code at codepade
You are apparently using a compiler with 64-bit pointers and 32-bit ints. Because you have declared a incorrectly, when you increment *a you are incrementing by the size of a pointer -- 64 bits, which is 8 bytes -- rather than the size of an int -- 32 bits, which is 4 bytes -- so effectively you increment by the size of two ints.
Change the declaration of a to
int* a[2];
and your program will behave correctly. Also, compile with -Wall (at least) to get warnings.
You are incrementing the pointer itself and again printing it..
So,
printf("%d",*(++(*a)));//would print 2
printf("%d",*(++(*a)));//would print 3
You should use *((*a)+1)
#include<stdio.h>
int main(void)
{
int a1[] = {1,2,3,4,5,6};
int a2[] = {7,8,9,10,11,12};
int *a3 = a1;
int *a4 = a2;
int **a[2];
a[0] = &a3; // a3 is a pointer, so take its address to get a pointer to pointer
a[1] = &a4; // same here
printf("%d",*(*(a[0])+1)); // PRINTS 2
printf("%d",*(*(a[1])+1)); // PRINTS 8
return 0;
}

But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so? [duplicate]

This question already has answers here:
Stack pointer difference for char pointer and array
(1 answer)
C pointers and arrays/ 'sizeof' operator [duplicate]
(2 answers)
Closed 9 years ago.
Hi i was doing this exercise and wanted to get the size of array after i pass the pointer to the array to the function:
But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so?
Is this any way i could get the size of the array on the findPut function?
#include <stdio.h>
//global vars
int i,j;
//functions prototypes
void findPut(int *, int);
int main(void){
int ins=4;
int arr[10]={1,2,3,5,6,7,8};
printf("%d\n",sizeof(arr)); //gives 40
int *ap=arr;
printf("%d\n",sizeof(*ap)); //gives 4 instead of 40 why?? if ap and arr the same thing
findPut(ap, ins);
return 0;
}
//functions
void findPut(int *p, int n){
//vars
//getting size of array
int size= sizeof(*p);
//sizeof(int);
printf("%d\n",size); //gives 4 but expected 40????
}
When you dereference *p you get an int, so it returns 4 (which is the size of int on your platform).
Because, sizeof(*ap) means sizeof(arr[0]); since array is of type int, sizeof(int), since in your system configuration, int is of size 4 you got the result as 4.
You can try it your self by printing the value of *p, you will get the value of arr[0].
Let int *p be a pointer and int arr[10]
Please note that:
Arrays and Pointers are not equivalent.
sizeof operator is a compile time operator.
sizeof(arr), evaluates to 10*sizeof(int), that is 10*4=40 in your case.
When you dereference p (getting the value that p points to), it doesn't give you whole array, but one unit of
your array that is an int so, *p means arr[0]. sizeof(arr[0]) is
4 (in your case) that's obvious.
When you use sizeof(p), it will give you the size of the pointer in your machine.
In my machine it is 8.
main function's return type should be int always. It has to retport operating system the exit status of the program. If you use void it might return random garbage.
The example demonstrate the issue:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *p=NULL;
int arr[10]={10,1,2,3,5,6,7,8,9,10};
p=arr;
printf("values: arr[0]=%d *p= %d\n\n",arr[0],*p);
printf("sizes : sizeof(arr[0])=%lu, sizeof(*p)= %lu sizeof(int)=%lu\n\n",sizeof(arr[0]),sizeof(*p),sizeof(int));
printf("Sizeof pointer p: %lu \n\n",sizeof(p));
printf("Sizeof arr: %lu \n\n",sizeof(arr));
printf("Pointing p to the first byte of 100 byte sequence\n\n");
p=malloc(100);
printf("Though p is pointing 100 byte block, sizeof(p)=%lu",sizeof(p));
return 0;
}
Essentially, sizeof evaluates the sizeof type but not the sizeof type it points to.
Thank you, i do appreciate your knowledge but is there any way i could
find the size of array inside another function( not the one where i
define the array).
You can't in my IMHO! You have to pass the size along with the array.
Example:
int main(){
int arr[10]={10,1,2,3,4,5};
printf("Length of array: %lu",findLength(arr,sizeof(arr)));
return 0;
}
size_t findLength(int *p,int size){
return size/sizeof(*p);
}
You have an int array and an int pointer:
int arr[10] = {1,2,3,5,6,7,8};
int* ap;
ap = arr;
In C, the expression arr is equivalent to &arr[0]. It stands to reason, then, that *ap is equivalent to arr[0], which is an int, which for your binary has a size of 4.
You also need to understand that arrays and pointers aren't the same thing. You may have been confused by the fact that arrays and pointers are often used interchangeably in the sense that a pointer can store the address of the beginning of an array (its first element, in other words) and navigate the consecutive addresses as if it had the actual array passed to it.

Arrays decaying into pointers

Please help me understand the programs below.
#include<stdio.h>
int main()
{
int a[7];
a[0] = 1976;
a[1] = 1984;
printf("memory location of a: %p", a);
printf("value at memory location %p is %d", a, *a);
printf("value at memory location %p is %d", &a[1], a[1]);
return 0;
}
&a[1] and &a+1. Are they same or different?
#include <stdio.h>
int main()
{
int v[10];
int **p;
int *a[5];
v[0] = 1234;
v[1] = 5678;
a[0] = v;
a[1] = v+1;
printf("%d\t%d\t%d\t%d\n", *a[0],*a[1],a[0][0],**a);
printf("%d\n", sizeof(v));
return 0;
}
I wanted to know how *a[5] is represented in memory. Is *a a base pointer that points to a[0],a[1],a[2],a[3],a[4]?
#include<stdio.h>
int main()
{
int v[10];
int **p;
int (*a)[10];
a=&v;
printf("%d\n",*a);
return 0;
}
a=v; // gives error why? does v here decay into *v. Then does &v get decayed into (*)[]v? & means const pointer. Here, how is it possible to set a const pointer to a non-const pointer without a typecast?
Where does the array get stored in the memory. Does it get stored onto the data segment of the memory.
#include<stdio.h>
int main()
{
int carray[5]={1,2,3,4,5};
printf("%d\n",carray[0]);
printf("%d\t%d\t%d\n",sizeof(carray),sizeof(&carray),sizeof(&carray[0]));
return 0;
}
EDITED:
I have gone through some of the articles which stated that the only two possible situations where an array name cannot be decyed into pointer is the sizeof and &. But in the above program sizeof(&carray) gives the size as 4. and &carray decays into (*)[]carray as its an rvalue.
Then the statement that array name cannot get decayed into pointers on two conditions sizeof and & becomes false here.
&a[1] and &a+1. Are they same or different?
Different. &a[1] is the same as (a+1). In general, x[y] is by definition equivalent to *(x+y).
I wanted to know how *a[5] is represented in memory. Does *a is a base
pointer that points to a[0],a[1],a[2],a[3],a[4].
In your second example, a is an array of pointers. *a[i] is the value of the object, the address of which is stored as the ith element in your array. *a in this case is the same as a[0], which is the first element in your array (which is a pointer).
a=v //why this gives error
Because a (in your last example) is a pointer to an array. You want to assign to a, then you need to assign the address of the array v (or any other array with correct dimensions);
a = &v;
This is very good that you've commited to understanding things, but nothing will help you better than a good C book.
Hope this helps.
Stuff you are gonna need to know when dealing with pointers is that:
int *a and int a[]
is a declaration of an Array, the only diffrence is that in a[] youre gonna have to declare its constant size, *a gives you flexability, it can point at an array size 1 to infinity
int *a[] and int **a
is a declaration of an Array of Array,sometimes called Matrix, the only diffrence is that in *a[] youre gonna have to declare how many Arrays a[] gonna contain pointers of, **a gives you flexability, it can point at any Array of arrays that you want it to be assigned to.
IN GENERAL:
When adding & to a variable, your adding a * to its Type definition:
int a;
&a -> &(int)=int*
when adding * to a variable, you decrase a * from its Type definition
int *a;
*a -> * (int * )=int
int *a;
&a - the Address given to the pointer a by the system(pointer of pointer = **a)
&a+1 - the Address to the beginning of the array + 1 byte
&a[1] == &(a+1) - the Address to the beginning of the array + 1 size of int
int **a;
*a == a[0] - the Address of the first Array in the array of arrays a
*a[0]==a[0][0] - the first int of first array
int *a, b[5];
*a=*b - ERROR because a points at garbage to begin with
a=b - a points at array b
ask me what else you want to know and ill edit this answer.

Resources