int check_authentication(char *password)
// 1
{
int auth_flag = 0;
char password_buffer[16];
strcpy(password_buffer, password); // 2
if(strcmp(password_buffer, "brillig") == 0)
auth_flag = 1;
if(strcmp(password_buffer, "outgrabe") == 0)
auth_flag = 1;
return auth_flag;
}
check_authentication(argv[1]) // Passing a 'Command Line argument'
// ( which is a string in this example) to the check_authentication function.
I have two questions reg. the lines labelled 1 and 2 above,
The function expects a character pointer as an argument. But we pass a "string" i,e an array of characters as an argument. How ?????
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.
You are passing a character pointer which points to the first character in the string. You aren't actually passing the whole string.
The strcpy
function reads the character being pointed to by this pointer, and then keeps reading successive characters from the next memory location until it encounters a null terminator.
The first argument of strcpy
, and both arguments of strcmp
, work in the same way.
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??
Strings are really just arrays of characters that are terminated with a null byte \\0
. The array is the string itself, the char pointer however is the memory location of the zeroth position of the array.
strcpy
reads characters beginning from the memory location pointed at by the char pointer until it encounters the null termination character.
Array actually isn't passed as such. What gets passed is a pointer to the very first element of the array. A string in C is actually an array of chars with a terminating NUL
and it's a pointer to its first element that gets passed.
You really should read strcpy
manpage carefully http://linux.die.net/man/3/strcpy . No addresses ever get copied there. All the function does is taking a string (an array of chars) password
pointer points at and copy all the chars found at that address up to the NUL
to the address pointed by password_buffer
pointer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.