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.
barray , typeint[2],bdecaysint*address first element in expressions (read: some exceptions array name not decaying pointer first element?). ,b + 1points nextintelements in array (notice diagram).&baddress 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