Pointers and Arrays in C

Most newbies  are often confused between pointers and arrays in C programming , In fact they assume them to be  more or less one and the same , so are  pointers and arrays equivalent ?  lets find out

Case 1:

Consider the following code snippet

#include <stdio.h>
int main()
{
    char arr[] = "techveda.org";
    char* ptr = arr;

    printf("%c %cn", arr[4], ptr[4]);
    printf("%c %cn", *(arr+2), *(ptr+2));

    return 0;
}
root@ubuntu:~# gcc arr.c -o arr
root@ubuntu:~# ./arr
v v
c c

Both the cases extract the same element of the string  so we can now conclude that Pointer arithmetic and array indexing are equivalent,  indexing works on both arrays and pointers. Similarly, pointer arithmetic works on both arrays and pointers.

Case 2:  So how are they different? 

#include <stdio.h>

char arr[100] = "techveda.org";
char* ptr = "techveda.org";

int main()
{
    char a = arr[7];
    char b = ptr[7];
    return 0;
}

What exactly happens in the assignment to a, and how is it different from the assignment to b? lets find out looking at assembly instructions  generated for both of the assignment expressions

root@ubuntu:~# vim ptr.c 
root@ubuntu:~# gcc -S ptr.c -o ptr.s
root@ubuntu:~# vim ptr.s
       .file   "ptr.c"
        .globl  arr
        .data
        .align 32
        .type   arr, @object
        .size   arr, 100
arr:
        .string "techveda.org"
        .zero   87
        .globl  ptr
        .section        .rodata
.LC0:
        .string "techveda.org"
        .data
        .align 4
        .type   ptr, @object
        .size   ptr, 4
ptr:
        .long   .LC0
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        subl    $16, %esp
        movzbl  arr+7, %eax
        movb    %al, -2(%ebp)
        movl    ptr, %eax
        movzbl  7(%eax), %eax
        movb    %al, -1(%ebp)
        movl    $0, %eax
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
        .section        .note.GNU-stack,"",@progbits

The semantics of arrays in C dictate that the array name is the address of the first element of the array. Hence in the assignment to a, the 8th character of the array is taken by offsetting the value of arr by 7, and moving the contents pointed to by the resulting address into the al register, and later into a.

  movzbl  arr+7, %eax
  movb    %al, -2(%ebp)

On the other hand, the semantics of pointers are quite different. A pointer is just a regular variable that happens to hold the address of another variable . Therefore, to actually compute the offset of the 8th character of the string, the CPU will first copy the value of the pointer into a register and only then increment it.

movl    ptr, %eax
movzbl  7(%eax), %eax
movb    %al, -1(%ebp)

Memory View

array

The rightmost column is the memory addresses, and the boxes are the contents of memory cells. The first letters of the string in arr are displayed.

Note that arr is simply a label (or an alias) to the memory address 0×317000. Therefore accessing arr[7] is simply accessing memory address 0×317007. Therefore, as we can see in the disassembly, the compiler just replaces arr[7] by 0×317007 – no address computation has to be done by the assembly it generates.

pointer

With a pointer, this works differently,ptr is just a variable that contains an address inside . This is the address to the first byte of the string that sits in another memory location. Compare this to the disassembly listing of the access to ptr[7] – it becomes clear why the compiler generates that code.

variable is just a convenient, alphanumeric pseudonym of a memory location. Were we writing assembly code, we would just create a label in some memory location and then access this label instead of always hard-coding the memory value – and this is what the compiler does. A label is something the compiler assigns at compile time. From here the great difference between arrays and pointers in C stems.

Case 3: Arrays as arguments to  functions 

#include <stdio.h>

char arr[100] = "techveda.org";
char *ptr = "techveda.org";

void func(char arr_arg[], char *);

int main()
{
        func(arr, ptr);
        return 0;
}

void func(char arr_arg[100], char *ptr_arg)
{
        char a = arr_arg[7];
        char b = ptr_arg[7];
        printf("%c,%c n", a, b);
}
root@ubuntu:~# gcc ptr1.c 
root@ubuntu:~# ./a.out 
a,a 
root@ubuntu:~#

how are the accesses to a and b different here? they’re not! This happens because arrays passed into functions are always converted into pointers. look at the assembly code for func

func:
.LFB1:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        subl    $40, %esp
        movl    8(%ebp), %eax
        movzbl  7(%eax), %eax
        movb    %al, -10(%ebp)
        movl    12(%ebp), %eax
        movzbl  7(%eax), %eax
        movb    %al, -9(%ebp)
        movsbl  -9(%ebp), %ecx
        movsbl  -10(%ebp), %edx
        movl    $.LC1, %eax
        movl    %ecx, 8(%esp)
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc

When an array name is passed to a function, what is passed is the location of the initial element. Within the called function, this argument is a local variable, and so an array name parameter is a pointer, that is, a variable containing an address. The C compiler has no choice here, since an array name is a label it replaces at compile time with the address it represents. But a function isn’t called at compile time, it’s called at run time, where something should be placed on the stack to be considered as an argument. The compiler can’t just treat array references inside a function as labels and replace them with addresses, because it has no idea what actual array will be passed in at run time.

Case 4:

One way is that arrays just can’t be manipulated the way pointers can. There is one difference between an array name and a pointer that must be kept in mind. A pointer is a variable, so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal.

#include <stdio.h>

int main()
{
    int i;
    char array[] = "techveda";
    char* ptr = array;

    /* array traversal */
    for (i = 0; i < sizeof(array); ++i)
        printf("%c ", array[i]);

    printf("n");

    /* pointer traversal */
    for (; *ptr; ++ptr)
        printf("%c ", *ptr);

    return 0;
}

let’s compile and execute

root@ubuntu:~# gcc ptr3.c 
root@ubuntu:~# ./a.out 
t e c h v e d a  
t e c h v e d a

Note how an array has to be indexed with another variable. A pointer, on the contrary, is just a variable that can be manipulated freely. Another, more important, difference is Suppose one file contains a global array:

char my_arr[256];

confused by seeming equivalence between arrays and pointers, the programmer that wants to use it in another file if mistakenly declares as:

extern char* my_arr;

When he tries to access some element of the array using this pointer, he will most likely get a segmentation fault.

Tags: , ,

6 Responses to “Pointers and Arrays in C”

  1. Pranay says:

    Nice article. Can you post any information on “Self-Referential structures” and how they are interpreted during compile, link and build stages

    Current score: 0
  2. Pranay says:

    Nice Article. Can you please post any information on “Self-Referential Structures” and how they are interpreted during the compile, link and build stages.

    Current score: 0
  3. dilipkumar says:

    nice article sir

    Current score: 0
  4. Nikhil AR says:

    Good article. Nicely written.

    Current score: 0
  5. techveda says:

    thanks, for the feedback, we will look into your request.

    Current score: 2
  6. guru says:

    good information plz post about volatile and volatile const

    Current score: 2

Leave a Reply