The function expects a character pointer as an argument. But we pass a "string" i,e an array of characters as an argument. How ?????
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 of the array.
When you call
strcpy(password_buffer, password);
the expression password_buffer
has type "16-element array of char
"; since the expression is not the operand of the sizeof
or unary &
operators, the expression is converted ("decays") to type "pointer to char
", and the value of the expression is the address of the first element. This pointer value is what gets passed to strcpy
.
In short, any time you pass an array expression to a function, the function will receive a pointer value. In the context of a function parameter declaration, T a[]
and T a[N]
will be interpreted as T *a
.
Believe it or don't, Ritchie did have reasons for designing the language this way; refer to this paper for details (look for the section titled "Embryonic C").
The address held by the pointer "password" (that points to a character) is copied to the "password_buffer" array. It makes no sense to me . Pls explain.
That's not what's happening; what's happening is that strcpy
is copying the contents of the buffer starting at the address given by password
to password_buffer
. Imagine the following memory map:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
"foo" 0x7fffc7cf4b22 'f' 'o' 'o' 0
argv[1] 0x7fffc7cf2670 0x00 0x00 0x7f 0xff
0xc7 0xcf 0x4b 0x22
password 0x7ffffdbe1878 0x00 0x00 0x7f 0xff
0xfd 0xbe 0x2v 0x22
password_buffer 0x7ffffdbe1880 0x?? 0x?? 0x?? 0x??
0x?? 0x?? 0x?? 0x??
0x?? 0x?? 0x?? 0x??
0x?? 0x?? 0x?? 0x??
where 0x??
indicates an unknown/indeterminate byte value.
The command line argument string "foo" is stored at address 0x7fffc7cf4b22
. Note that in C, a string is simply a sequence of character values terminated by a 0-valued byte. Strings are stored as arrays of char
(const char
in C++), but not all arrays of char
contain a string.
The argv[1]
expression evaluates to the address of the first command line argument, which is the address of the string "foo"
, which is 0x7fffc7cf4b22
. This value is passed to the check_authentication
function and is stored to the password
parameter. Note that argv[1]
and password
are different items in memory (they have different addresses), but both contain the same value (the address of the string "foo"
).
The password_buffer
array starts at address 0x7ffffdbe1880
. Since it wasn't declared static
and doesn't have an explicit initializer, the contents of the array are indeterminate.
The strcpy
function copies the contents of the string starting at address 0x7fffc7cf4b22
into the buffer starting at address 0x7ffffdbe1880
until it sees that 0-valued byte. After the call to strcpy
, our memory looks like this:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
"foo" 0x7fffc7cf4b22 'f' 'o' 'o' 0
argv[1] 0x7fffc7cf2670 0x00 0x00 0x7f 0xff
0xc7 0xcf 0x4b 0x22
password 0x7ffffdbe1878 0x00 0x00 0x7f 0xff
0xfd 0xbe 0x2v 0x22
password_buffer 0x7ffffdbe1880 'f' 'o' 'o' 0
0x?? 0x?? 0x?? 0x??
0x?? 0x?? 0x?? 0x??
0x?? 0x?? 0x?? 0x??