this code sample prints array correctly.
int b[2] = {1, 2}; int *c = &b; int i, j,k = 0; (i = 0;i < 2; i++) { printf("%d ", *(c+i)); }
while 1 prints 2 garbage values.
int b[2] = {1, 2}; int i, j,k = 0; (i = 0;i < 2; i++) { printf("%d ", *(&b+i)); }
why 2 code samples behaving differently?
the declaration:
int b[2] = {1, 2};
creates array of 2 int
values 1
, 2
.
suppose in system size of int 4-bytes, array b[]
should stored in memory follows:
first ele +----------+ (b + 0) ---►| 1 | 0xbf5c787c <----- &b , (c + 0) next ele +----------+ (b + 1) ---►| 2 | 0xbf5c7880 <------------- (c + 1) +----------+ (b + 2) ---►| ? | 0xbf5c7884 <----- (&b + 1) next array +----------+ ---►| ? | 0xbf5c7888 +----------+ ---►| ? | 0xbf5c788c <----- (&b + 2) next array +----------+ ---►| ? | 0xbf5c7890 +----------+ ? means garbage value b[] array in memory 0xbf5c787c 0xbf5c7880 each cell 4 bytes
in above diagram memory cells value ?
means garbage values , not allocated (memory 0xbf5c7884
not allocated in our array). values 1
, 2
stored in memory @ address 0xbf5c787c
, 0xbf5c7880
, allocated in array b[]
.
let's instead of printing values, print addresses of memory access in code using (c + i)
, (&b + i)
, consider following program:
#include<stdio.h> int main(){ int b[2] = {1, 2}; int = 0; int *c = &b; //give warning: "assignment incompatible pointer type" printf("\n c address: "); // outputs correct values (i = 0; < 2; i++) { printf("%p ", (void*)(c + i)); } printf("\n b address: "); // outputs incorrect values/ , behaving differently (i = 0; < 2; i++) { printf("%p ", (void*)(&b + i)); // undefined behavior } return 1; }
outputs:
c address: 0xbf5c787c 0xbf5c7880 b address: 0xbf5c787c 0xbf5c7884
check code working @codepade
notice, (c + i)
prints correct address of cells value 1
, 2
hence outputs in first code correct. whereas (&b + i)
prints address value not allocated array b[]
(that outside of array b[]
) , accessing memory gives undefined behaviour(unpredictable) @ runtime.
actually there difference between b
, &b
.
b
array , typeint[2]
,b
decaysint*
address first element in expressions (read: some exceptions array name not decaying pointer first element?). ,b + 1
points nextint
elements in array (notice diagram).&b
address of complete array , typeint(*)[2]
,(&b + 1)
points next array of typeint[2]
not allocated in program (notice in diagram(&b + 1)
points).
to know other interesting differences between b
, &b
read: what sizeof(&array)
return?
in first code snipe, when c = &b
, assigning array's address int*
(in our example 0xbf5c787c
). gcc compiler statement give warning: "assignment incompatible pointer type".
because c
pointer int
, *(c + i)
prints integer stored @ address (c + i)
. i = 1
value (c + 1)
points second element in array (in our example @ 0xbf5c7880
) hence *(c + 1)
prints 2
correctly.
regarding assignment int *c = &b;
in first code highly suggest read @andreyt's answer below. correct , simple way access array elements using pointer follows:
int b[2] = {1, 2}; int *c = b; // removed &, `c` pointer int int i; (i = 0; < 2; i++){ printf("%d ", *(c + i)); // printf("%d ", c[i]); // correct statement }
in second code, adding i
&b
make pointing outside allocated memory , in printf statement access memory using *
dereference operator cause invalid memory access , behavior of code @ run time undefined. reason second piece of code behaving differently @ different execution.
your code compiles because syntactically correct, @ runtime accessing of unallocated memory can detected os kernel. may causes os kernel send signal core dump process caused exception (interesting note: os detects memory right violation process -- invalid access valid memory gives: sigsegv, , access invalid address gives: sigbus). in worth case program may execute without failure , produce garbage results.
regarding second code, correct way print array using 'pointer array' below:
#include<stdio.h> int main(){ int b[2] = {1, 2}; int i; int (*c)[2] = &b; // `c` pointer int array of size 2 for(i = 0; < 2; i++){ printf(" b[%d] = (*c)[%d] = %d\n", i, i, (*c)[i]); // notice (*c)[i] } return 1; }
output:
b[0] = (*c)[0] = 1 b[1] = (*c)[1] = 2
check @codepade. point notice parenthesis around *c
needed precedence of []
operator higher *
dereference operator (whereas if use pointer int don't need parentheses in above code).
Comments
Post a Comment