Array, pointer and Sizeof relation [duplicate] - c

This question already has answers here:
Is an array name a pointer?
(8 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
How Does sizeof(Array) work
(5 answers)
Closed 5 years ago.
I have learned that we can use the address of elements of an array at index i as &A[i] or simply as A+i
and to get the value
A[i] or *(A+i)
where A is an array and i denotes the Index.
Let's say int A[]={1,2,3};
When I use sizeof(*A) I get value 4, now when I use sizeof(A) I must get the size of address value of the first element why I get the size of the whole array as 12.
I am a beginner and confused, please guide.

int A[]={1,2,3};
A is an array and array is not a pointer. when you are printing sizeof(*A) it prints 4 because *A means first element of array which size is 4.
sizeof(A) will results not result in 4 because A is not a pointer. A is an array and array means collection of elements and each elements needs 4 bytes.
A[i] == *(A+i)
sizeof(A[i]) => 4 because A[0] is an integer
sizeof(*A) => 4 because *A means value at starting address and that needs 4 bytes to store
sizeof(A) => 12 bytes, not 4 because A is not a pointer.
sizeof(&A[0]) => 4 bytes because &A[0] yields in address and size of any address will be 4 bytes.

When you call sizeof(A) you get the size of the array as n.m said. But If you initialize your array as this:
int *A = new int[3];
A[0] = 1;
A[1] = 2;
A[2] = 3;
cout << sizeof(A) << endl;
you will get 4.

When I use sizeof(*A) I get value 4
This is nothing but size of first element in the array ie sizeof(*A) is the same as sizeof(*(&A[0])).
now when I use sizeof(A) I must get the size of address value of the first element why I get the size of the whole array as 12
You have declared A as
int A[]={1,2,3};
Now, ask yourself a simple question - What is A ? Never settle with anything other than Array for an answer. In short you get the size of entire array in bytes. Here you have 3 elements which takes 4 bytes each.
Added
I must get the size of address value
That should be sizeof(&A) - which is the size of the address of A - which is usually 8 bytes in many systems.

Related

What the following code prints / with arrays, pointers etc

I have problem solving this problem, so if anyne had a similar problem it would help me a lot.
short y[2][3]={{0123},{0x12345}},*p=y[1];
printf("01:%x\n", y);
printf("02:%x\n", p);
printf("03:%x\n", sizeof(y));
printf("04:%x\n", sizeof(y[0]));
printf("05:%x\n", sizeof(&y[0]));
printf("06:%x\n", sizeof(*p));
printf("07:%x\n", sizeof(p++));
printf("08:%x\n", *p++);
printf("09:%x\n", *p);
return 0;
Can anyone explain to me why the printout is like this?
01:61ff10
02:61ff16
03:c
04:6
05:4
06:2
07:4
08:2345
09:0
My opinion:
01:Prints the address where the array y begins.
02:Prints the address of the pointer, which points to the second element of the array. Since we have 2 * 3 elements that are of type short, each subsequent element of the zero element will increase by 6.
03:Since we have 2 * 3 elements, which is equal to 6, but the elements of the type are short, so it will print hexadecimal c
04:the number of elements in the zero position is 3, but they are of the short type, so it prints 6
05:prints the sizeof addresses of the first element of the array which is 4
06:I don't know why it prints 2 here
07:Prints the sizeof of the pointer address which is 4, it will increase after printing
08:I do not understand
09:I do not understand
Can anyone explain why it prints like this?
OK, let's see:
#01: The address of y.
#02: The value of p, which holds the address of y[1], which is the second element of type short[3]. The size of a short is apparently 2 on your system, so the offset to #01 is 6.
#03: The size of the array y, 2 * 3 * sizeof (short) give 12, in hex c.
#04: The size of the element y[0], which is of type short[3]. 6, as you found.
#05: The size of the address of y[0], and apparently the size of an address is 4 on your system.
#06: The size of the object that p points to. This is a short, so 2.
#07: The size of the expression p++, which is an address, so 4. And no, p is not incremented, since the expression is not evaluated.
#08: The value of the object that p points to, which is y[1][0]. Since the initializing value of 0x12345 is an int too big to be stored in a short, it is truncated to 0x2345. After reading the value, p is incremented.
#09: The element p points to, which is y[1][1]. It was initialized to 0.
Notes:
You should have got warnings from your compiler:
The mentioned initializer is truncated.
The format for pointers/addresses is %p.
The type of the result of sizeof might not match the format %x.
You should take warnings seriously, they are always a hint that you most probably made an error.
N6) Sizeof(*p) is size of datatype pointed by p. p is pointer to short: so 2 bytes.
N8) p is pointer to short, it`s pointing to array element y[1][0].
y[1] and y[1][0] have the same memory address.
All array elements are short, 0x12345 truncates to 0x2345 upon array initialisation. So output is 2345.
Also, p++ increases pointer value to point to next short y[1][1].
N9) Because of p++ in step N8, pointer now points to y[1][1], which was initialised to 0 (by default, because init value not provided) - output is 0.

Subtracting addresses in a 3d array

I created a 3d array
a[2][3][2]
Now when I try to print
printf("%d",a[1] - a[0]);
I get 3 as the output.
What I understand is that a[1] gives me the address of a[1][0][0] element and a[0] the address of a[0][0][0].
Let Address of a[0][0][0] is BA then Address of a[1][0][0] is BA + 4*2*3 where 4 byte is the memory space of an integer datatype
I was expecting the result to be 6.
Similarly I tried
printf("%d",(&a + 1) - &a);
and the output received was 1.
Where am I going wrong?
Edit 1: Entire Code
#include<stdio.h>
int main(){
int a[2][3][2] = {{{1,2},{3,4},{5,6}},{{7,8},{9,10},{11,12}}};
printf("%d",a[1]-a[0]);
return 0;
}
What I understand is that a[1] gives me the address of a[1][0][0] element and a[0] the address of a[0][0][0].
This is wrong a[0] will give the address of the first 2D array. The address of the first 2D array and the address of a[0][0][0] might be co-incident, but they are not the same.
Specifically &a +1 is not equal to &a[0][0][0] +1
Let's break the expression a[1] - a[0] apart:
a[1] - refers to the second [3][2] array.
a[0] - refers to the first [3][2] array.
Now, when arrays are used in most contexts, they decay into pointers to the first element. So a[i] will decay into a pointer to a 2d array int(*)[2].
The difference is calculated in sizeof(int[2]) as dictated by pointer arithmetic. And you can see that there are 3 units of int[2] in the range [a[0], a[1]).

Proper way to iterate throught list of pointers?

I can't wrap my head about idea of array of pointers. Problem is I'm trying to iterate throught list of pointers (or at least get second value from pointer's array). I understand that integer is 4 bytes long (assuming im on 32-bit). And what I'm trying to do is get first address that points to a[0] and add to this address 4 bytes, which in my opinion will result in a[1]. However, this works as I'm just adding value to index. I.e. f[0] + 4 -> f[5]
And I don't quite understand why.
#include "stdio.h"
int main()
{
int a[6] = {10,2,3,4,20, 42};
int *f[6];
for(int i = 0; i < sizeof(a)/sizeof(int); i++) f[i] = &a[i];
for(int i = 0; i < sizeof(a)/sizeof(int); i++) printf("Current pointer points to %i\n", *(*f+i));
printf("The is %i", *(f[0]+sizeof(int)));
return 1;
}
Pointer arithmetic takes into account the size of the pointer.
f[0] + 4 will multiply 4 by the size of the integer type.
Here's an online disassembler: https://godbolt.org/.
When I type the code f[0] + 4, the disassembly appears as
add QWORD PTR [rbp-8], 16
Meaning it has multiplied the 4 by 4 (32-bit = 4 bytes) to make 16.
An array is a pointer to a chunk of RAM. int a[6] = {10,2,3,4,20, 42}; actually creates a chunk with [0x0000000A, 0x00000002, 0x00000003, 0x00000004, 0x00000014, 0x0000002A], and a points to where the list starts.
Using an index a[n] basically means go to the position of a (start of the array), then advance by n*sizeof(int) bytes.
a[0] means Go to position of a, then don't jump
a[1] means Go to position of a, then jump 1 time the size of an integer
a[2] means Go to position of a, then jump 2 times the size of an integer
supposing a is at the address 0xF00D0000, and you're on a 32bit machine:
a[0] // Pointer to 0xF00D0000
a[1] // Pointer to 0xF00D0004
a[2] // Pointer to 0xF00D0008
a[32] // Pointer to 0xF00D0080
I hope this makes sense.

different representation of array element [duplicate]

This question already has answers here:
With arrays, why is it the case that a[5] == 5[a]?
(20 answers)
Closed 9 years ago.
consider following C code
int a[]={1,2,3,4};
printf("%d",2[a]);
this prints "3".How is it possible? I know in a[2] a is the base address of array.But in 2[a]
what is 2? and how it accessses array a?I am totally confused with this representation of array.
There are two things to remember here:
The first is that array access is basically just a fancy way of using pointer arithmetic. For example, if you have the array
int a[10];
then
a[3] = 5;
is equal to
*(a + 3) = 5;
The second thing to remember is that addition (like in a + 3 above) is commutative, so a + 3 is the same as 3 + a. This leads to e.g.
*(3 + a) = 5;
which can be interpreted as
3[a] = 5;
int a[]={1,2,3,4}; is an integer array containing 4 elements and a is the Base Address, Let the Base Address be denoted by X . Now a[1] means element at address X + sizeOf(int) * 2 = Y (suppose) i.e. element at address Y, likewise 2[a] means element at adsress sizeOf(int) * 2 * X = Y.
Thus even if you write a[2] or 2[a] eventually complier recognizes it as Y and refres to the element at address Y which is 3 in our case.
Hope it addresses the problem right.
*(expr1+expr2) is equivalent to expr1[expr2] or expr2[expr1].
*(expr2+expr1) is equivalent to expr2[expr1] or expr1[expr2].
It is just another way to write an element of an array.
In int a[]={1,2,3,4};, element at index 3 can be referenced by many methods:
As an array element: a[3]
Using pointer: *(a + 3) or *(3 + a) [Addition is commutative in arithmetics and in C]
Now you can write the second way of representation using pointer as 3[a], i.e. a[3] is equal to *(a + 3) is equal to *(3 + a) is equal to 3[a].

2-D array in C, address generation

How do addresses get generated in arrays in C, say how does a [x][y] get to a particular value, i know its not that big a question but just about to actually start coding.
Well it is done depending on your data type of whose array you have considered.
Say for an Integer array, each value holds 4 bytes, thus a row X long will take 4X bytes.
Thus a 2-D matrix of X*Y will be of 4*X*Y Bytes.
Any address say Arry[X][Y] would be
calculated as : (Base Address of Arry)
+ (X * No. of columns) + ( Y // Offset in current row )
2-dimensional arrays in C are rectangular. For example:
int matrix[2][3];
allocates a single block of memory 2*3*sizeof(int) bytes in size. Addressing matrix[0][1] is just a matter of adding 0 * (3 * sizeof(int)) to sizeof(int). Then add that sum to the address at which matrix starts.
A nested array is an array of arrays.
For example, an int[][6] is an array of int[6].
Assuming a 4-byte int, each element in the outer array is 6 * 4 = 24 bytes wide.
Therefore, arr[4] gets the third array in the outer array, or *(arr + 4 * 24).
arr[4] is a normal int[]. arr[4][2] gets the second int in this inner array, or *(arr + 4 * 24 + 2 * 4)
E.g.
char anArray[][13]={"Hello World!","February","John"};
You can visualize it as:
anArray:
H|e|l|l|o| |W|o|r|l|d|!|\0|F|e|b|r|u|a|r|y|\0|\0|\0|\0|\0|J|o|h|n|\0|\0|\0|0|\0
^ ^ ^
0 13 26

Resources