Printing pointer to pointer [closed] - c

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;
}

Related

Unexpected value when referencing a pointer

I'm playing with OnlineGDB compiler in order to understand how pointers work in C.
First, I ran the following code and got the output I expected:
int *array1[] = {1,4,3,4};
int main()
{
printf("%d \n", array1[0+1]);
printf("%d", array1[1+1]);
return 0;
}
Output was:
4
3
Secondly, I ran the following code - And I can't understand its output:
int *array1[] = {1,4,3,4};
int main()
{
printf("%d \n", array1[0]+1);
printf("%d", array1[1]+1);
return 0;
}
Output:
5
8
It seems like I'm adding 4 to the value from the array, but why? (each element in the array is consisted from a byte).
Thanks!
It seems like I'm adding 4 to the value from the array, but why?
No, each element of the array is an int * because you declared the array that way:
int *array1[] = {1,4,3,4};
That says array1 is an array whose values have type pointer to int. Remove the * if you want an array of int, like:
int array1[] = {1,4,3,4};
When you add or subtract from pointer types, the value changes by some multiple of the size of the type that the pointer refers to. An int on your system is probably 4 bytes, so an expression like array1[0]+1 gets the int * stored in array[0] and increments it, so it increases by sizeof(int).
(each element in the array is consisted from a byte).
Even if you had declared your array as an array of int rather than an array of int *, the size of an int is probably not 1 byte. int is typically 4 bytes long, but size depends on the compiler and target system.
With
int *array1[] = {1,4,3,4};
you are defining tan array of pointers to integers.
So every element of that array, even if initialized with what appear to be integer values, are actually pointers, that are addresses.
If you had deferenced those pointers you would probably have caused a segmentation fault. But fortunately you simply printed them, even if using %d instead of %p: a choice that according to C standard could have caused undefined behavior. Anyway in your case the pointers were converted to integers, and the printed values were the expected ones. Exactly like if the array was an array of integers.
In the second example you pushed it further: you added 1 to the array elements. But since they are pointers, then pointers arithmetics is applied. Meaning that pointer + N = pointer + N * sizeof(*pointer). In this case, since sizeof(int) is 4:
array[0] + 1 =
= 1 + sizeof (array[0]) =
= 1 + sizeof( int ) =
= 1 + 4 = 5

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.

Multiplying what's pointed to by pointers

Pointer1 points to 5.
Pointer2 points to 3.
I want to multiply 5*3, but I only have the pointers. How would I do this in C?
Also, what does uint32_t *pointer mean when:
pointer[2] = {1, 2};
I do not know what is so hard for the answerers to understand about this question. It is obviously about dereferencing pointers.
This is how you display the contents of the pointer that it is pointing to:
#include <stdio.h>
int main(void)
{
int num1 = 5;
int num2 = 3;
int* num1_ptr = &num1;
int* num2_ptr - &num2;
int sum = *num1_ptr * *num2_ptr;
printf("%d\n", sum);
return 0;
}
*num1_ptr and *num2_ptr takes your pointers and references what the contents of that memory address.
I can't answer the first half of your question without more information, but uint32_t* pointer is simply a pointer to an unsigned 32-bit integer value (unsigned int and uint32_t are usually equivalent types, depending on your compiler).
If I see a declaration that simply reads uint32_t* pointer without more information I'm going to assume it's a pointer to a single value, and that using the indexing operator [n] on such a pointer is basically overflowing the single-element-sized buffer. However if the pointer is assigned the result from an array or buffer function (e.g. malloc, calloc, etc) then using the indexing operator is fine, however I would prefer to see uint32_t pointer[] used as the declaration as it makes it much easier to determine the developer's intent.
uint32_t *pointer is just a pointer with garbage value unless you point it to something.
pointer[0] = 1;
pointer[1] = 2;
is only valid if you have earlier pointed it to some array of type uint32_t with atleast size two or to a block containing uint32_ts defined using malloc as follows:
uint32_t *pointer;
pointer = (uint32_t*)malloc(sizeof(int*SIZE); //SIZE > 2 here
or
uint32_t array[10];
pointer = & array[0]; // also, pointer = array; would also work.
int main(void)
{
int variableA = 5;
int variableB = 3;
int* ptr1 = &variableA; // Pointer1 points to 5.
int* ptr2 = &variableB; // Pointer2 points to 3.
int answer;
answer = (*ptr1) * (*ptr2); // I want to multiply 5*3, but I only have the pointers.
// Answer gets set to [value stored at ptr1(5)] MultipliedBy [value stored at ptr2(3)]
}
Your misconception is that pointers do not refer to values, such as 5 and 3.
pointers refer to variables, such as variableA and variableB; those variables have values which can be accessed and changed via the pointer.But the pointer only refers to the variable, not directly to the value behind it.

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

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

Array Pointers and Manipulation

Suppose I have:
int (* arrPtr)[10] = NULL; // A pointer to an array of ten elements with type int.
int (*ptr)[3]= NULL;
int var[10] = {1,2,3,4,5,6,7,8,9,10};
int matrix[3][10];
Now if I do,
arrPtr = matrix; //.....This is fine...
Now can I do this:
ptr = var; //.....***This is working***
OR is it compulsory to do this:
ptr= (int (*)[10])var; //....I dont understand why this is necessary
Also,
printf("%d",(*ptr)[4]);
is working even though we declare
int (*ptr)[3]=NULL;
^^^
In some cases, Name of Array is Pointer to it's First Location.
So, when you do,
ptr = var;
You are assigning address of var[0] to ptr[0]
int var[10] declaration makes var as an int pointer
As both are int pointers, the operation is valid.
For Second Question,
When you declare a Pointer, It points to some address.
Say
int * ptr = 0x1234; //Some Random address
now when you write ptr[3], it's 0x1234 + (sizeof(int) * 3).
So Pointer works irrespective of it's declared array size.
So when ptr = NULL,
*ptr[4] will point to NULL + (sizeof(int) * 4)
i.e. A Valid Operation!
ptr and var aren't compatible pointers because ptr is a pointer to an array of 3 ints and var is an array of 10 ints, 3 ≠ 10.
(*ptr)[4] works likely because the compiler doesn't do rigorous boundary checks when indexing arrays. This probably has to do with the fact that a lot of existing C code uses variable-size structures defined something like this:
typedef struct
{
int type;
size_t size; // actual number of chars in data[]
unsigned char data[1];
} DATA_PACKET;
The code allocates more memory to a DATA_PACKET* pointer than sizeof(DATA_PACKET), here it would be sizeof(DATA_PACKET)-1+how many chars need to be in data[].
So, the compiler ignores index=4 when dereferencing (*ptr)[4] even though it's >= 3 in the declaration int (*ptr)[3].
Also, the compiler cannot always keep track of arrays and their sizes when accessing them through pointers. Code analysis is hard.
ptr is a pointer to array of 3 integers, so ptr[0] will point to the start of the first array, ptr[1] will point to the start of the second array and so on.
In your case:
printf("%d",(*ptr)[4]);
works as you print the element no 5 of the first array
and
printf("%d",(*ptr+1)[4]);
print the element no 5 of the second array ( which of course doesn't exists)
for example the following is the same as yours
printf("%d",ptr[0][4]);
but this doesn't mean that you depend on this as var is array of 10 integers, so ptr has to be decelared as
int *ptr = NULL
in this case to print the element no 5
printf("%d", ptr[4]);

Resources