0

I write program to understand the differences between array and pointer :

#include <stdio.h>

void main()
{
    char arr [] ="hodaya",*ptr=arr;
    printf("arr=%p\n",arr);
    printf("&arr=%p\n",&arr);
    printf("ptr=%p\n",ptr); 
    printf("&ptr=%p\n",&ptr);
}

Result :

arr=0xbfd26265

&arr=0xbfd26265

ptr=0xbfd26265

&ptr=0xbfd26260

So I read the below answer:

how-come-an-arrays-address-is-equal-to-its-value-in-c

It answered most of my questions, I was left with one question!

I understand that when I defined pointer I defined (in specific address) a space for hold address and therefore I can to take the pointer address like this : &ptr.

But what happened when I defined array?

Community
  • 1
  • 1
Hodaya Shalom
  • 4,327
  • 12
  • 57
  • 111
  • 4
    You have undefined behaviour. `printf` expects `void *` when given `%p`. – chris Jul 28 '14 at 16:42
  • 1
    Nothing special occurs when you define an array. `char arr[] = "blah";` is no different to `char x = 'p';` - each defines a name that relates to some storage. – Oliver Charlesworth Jul 28 '14 at 16:43
  • @OliCharlesworth so it defined a space to hold some chars? and therefore the arr= &arr , cause arr is the address of the first place? (and not a pointer) – Hodaya Shalom Jul 28 '14 at 16:47
  • 1
    when you defined arr[], you created a memory block named arr which is large enough to hold "hodaya". – MAKZ Jul 28 '14 at 17:06
  • Think about `char x = '*';` vs. `char y[1] = { '*' };`. They are exactly the same on the machine level, they differ only in usage. (`y` decays to a pointer in certain circumstances, while `x` always needs explicit `&x`, …) – mafso Jul 28 '14 at 17:07
  • 2
    The confusing thing is that in many situations, an array automatically *decays* to a pointer to its first element. Due to this decay, when you're printing `array`, you're actually printing `&array[0]`. And indeed `array[0]` begins at the same address as `array`, therefore `&array[0]` has the same numerical value (though not the same type) as `&array`. – avakar Jul 28 '14 at 17:11
  • @avakar. it is the answer I searched for! put it like a answer =] – Hodaya Shalom Jul 28 '14 at 17:28
  • check this: http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c – Sam Liao Jul 28 '14 at 17:51

2 Answers2

3

First of all, unless your compiler documentation explicitly lists void main() as a valid signature for the main function, use int main(void) instead. Under most circumstances, main is supposed to return a value to the runtime environment (even if it's just EXIT_SUCCESS).

So let's talk about the declaration

char arr [] ="hodaya";

"hodaya" is a string literal; it is stored as a 7-element array of char (6 characters plus 0 terminator) such that it is allocated at program startup and held until the program exits. String literals are not meant to be modifiable, and attempting to update one results in undefined behavior (which can mean anything from your code crashing with an access violation to working as expected). You should always treat string literals as read-only and never pass them to functions that attempt to modify them (such as strcpy, strtok, etc.).

arr is declared as an array of char, and it will be initialized with the contents of the string literal "hodaya". The size of the array is taken from the size of the initializer (7). That declaration is roughly equivalent to:

char arr[7];
strcpy( arr, "hodaya" );

It could also be written as

char arr[] = {'h', 'o', 'd', 'a', 'y', 'a', 0 };

Same result (arr initialized with the string "hodaya"), slightly different syntax. In this case, no string literal is created.

Since you declared arr local to main (it is said to have automatic storage duration, meaning that memory will be released when the function exits), you can modify the contents of arr[0] through arr[6].

Now let's talk about the declaration for ptr.

Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element in the array. The result is not an lvalue; that is, it cannot be the target of an assignment.

This is important, and the source of a lot of confusion. arr is not a pointer; it does not contain an address. When the compiler sees arr in most contexts, it will replace it with the address of its first element, and the type of the resulting expression will be char *. If arr is the operand of the unary & operator, though, the substitution doesn't happen. The value of the expression is the same (the address of the array is the same as the address of the first element of the array), but the type of is different; instead of char *, the type of &arr is char (*)[7] (pointer to 7-element array of char).

Thus, in the declaration

char *ptr = arr;

arr is not the operand of the unary & operator (or any other), so the conversion rule applies, and the address of the first element of arr is written to ptr.

By the time you're done, your memory looks something like the following (addresses are not meant to reflect any real-world architecture):

Item            Address            0x00 0x01 0x02 0x03
----            -------            ---- ---- ---- ----
"hodaya"        0x40040             'h'  'o'  'd'  'a'
                0x40044             'y'  'a'   0    ??
                  ...
arr             0x7fffb220          'h'  'o'  'd'  'a'
                0x7fffb224          'y'  'a'   0    ??
ptr             0x7fffb228         0x7f 0xff 0xb2 0x28

Again, arr and ptr only exist for the lifetime of the function main. The string literal "hodaya" exists for the lifetime of the entire program.

NOTE: I compiled the example above (after fixing a few issues) on a SLES 10 box using gcc 4.1.2, and yes, it created an entry for the string literal in .rodata, even though it's only used to initialize arr.

John Bode
  • 119,563
  • 19
  • 122
  • 198
-3

arr holds the address of the first element in the array(&arr[0]).

Here you are always reading the address of the elements and not the value .

arr[0] = 'a', arr[1] = 'b', arr[2] = 'c', arr[3] = 0;

char *ptr = arr;
*ptr++ = 'a', *ptr++ = 'b', *ptr++ = 'c', *ptr = 0;
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
Gopi
  • 19,784
  • 4
  • 24
  • 36