Following the question: How come an array's address is equal to its value in C?
#include <stdio.h>
#define N 10
char str2[N]={"Hello"};
int main(){
printf("sizeof(str2): %d bytes\n", sizeof(str2));
printf("sizeof(&str2): %d bytes\n", sizeof(&str2));
return 0;
}
Output:
sizeof(str2): 10 bytes
sizeof(&str2): 4 bytes
I know that
str2
alone is the adress of the first element in array str2
. And that when str2
is an argument of sizeof
it returns the size of the whole array str2.
In addition,
&str2
is also the adress of the first element in arr str2
but from diffrent type (char (*)[N]
== pointer to array). But how &str2
behaves when it's an argument of sizeof
?
Answers:-
Difference between &str
and str
, when str
is declared as char str[10]
?
Read
sizeof
Operator:6.5.3.4 The sizeof operator, 1125:
When you apply thesizeof
operator to an array type, the result is the total number of bytes in the array.
So, according to your declaration,
Whereas in expression
sizeof(str2)
gives the complete array size that is 10 bytes (because N is defined 10, and char size is 1-byte).Whereas in expression
sizeof(&str2)
, &str2
is address of array and size of address that is 4 bytes in your system. (address size may 8 byte in some systems e.g 64-bit).In addition,&str2
is also the adress of the first element in arrstr2
?
No, values-wise both
&str2
and str
are same, but semantically both are different. One is address of an array of 10 chars while the other is is an address of a char.
One difference you have seen in your own example that how they are differences(and @ouah explained in this answer).
- type of
str
ischar[10]
- type of
&str
ischar(*)[10]
Second: Following diagram will help you to observe the other difference.
for declaration:
#define N 10
char str2[N] = {"Hello"};
str2 Array in memory is something like:
----------------------------------------
str
+----+----+----+----+----+----+----+----+----+----++----+
|'H' |'e' |'l' |'l' |'o' |'\0'|'\0'|'\0'|'\0'|'\0'|| '@'|
+----+----+----+----+----+----+----+----+----+----++----+
201 202 203 204 205 206 207 208 209 210 211
▲ ▲ ▲ ▲
| | | |
|(str2) (str2 + 1) |
| |
|-----------------------------------------------------|
|201 |
| |
| |
(&str2) = 201 (&str2 + 1) = 211
* assuming str address start from 201
* str[N] is 10 char long 201-210, partially initialized
* at uninitialized position, str2[i] = '\0'
* location 211 is unallocated, having garbage value,
access to this location is illegal-Undefined Behavior
For above diagram you can write a code:
#include <stdio.h>
#define N 10
int main(){
char str2[N]={"Hello"};
printf("\n %p, %p\n",str2, str2+1);
printf("\n %p, %p\n",(&str2), (&str2+1));
}
Output:
0xbf67e142, 0xbf67e143
0xbf67e142, 0xbf67e14c
Notice the first line output address difference is one byte, But in second line difference is 10 bytes because its array's pointer (as shown above in diagram).
According to pointer mathematics rules when you add 1 to pointer variable it start points to next element of its own type that is the reason 10 byte differences because
&str2
is array address..
Third difference:
By doing
*str2
you can access first element. Whereas *(&str2)
will not give you first element but it is address of first element.
An example will help here:
#include <stdio.h>
#define N 10
int main(){
char str2[N]={"Hello"};
printf("\n%p %c, %p %c\n",str2, *(str2), *(&str2), **(&str2));
}
output:
0xbf587046 H, 0xbf587046 H
In output
str2 gives 0xbf587046
*(str2) H
*(&str2) 0xbf587046
**(&str2) H
That means
*(&str2) == str2
and value is address. And hence *(str2) = **(&str2)
values isH
.
Edit: Above I shown difference between
&str
and str
where str
is an array of type char[10]
.
Difference between char *str
and char str[]
and how both are stored in memory
Suppose we have two declarations like below:
char *str1 = "hello";
char str2[] = "hello";
In above declarations
str1
is a pointer to char
, that points to a constant string literal (by holding address of first char h
in "hello"
string).
A string in C is of
char[N]
(array) type that is why sizeof("hello")
gives 6 because "hello"
string is 6 chars long array (included \0
nul, strings termination, type of hello is char[6]
).
In memory you
"hello"
string is stored like as below: str1 23 24 25 26 27 28
+----+ +----+----+----+----+----+----+
| 23 | | h | e | l | l | o | \0 |
+----+ +----+----+----+----+----+----+
+-----------▲
here address of hello string is first address = 23.
str1: is pointer capable to store address.
"hello" consists of 6 chars
char* str1 = "hello";
basically stores address of string hello to pointer variable str1
as I shown above in figure.
Note: If you wants lately in you code you change change
str1
to point some other string. But you can't modify hello
string. for example following code is valid: char* str1 = "hello"; // str1 points to hello str1-->"hello"
str1 = "world"; //Now, str1 points to world str1-->"world"
Now
str1
points to other constant string world. str1 93 94 95 96 97 98
+----+ +----+----+----+----+----+----+
| 93 | | w | o | r | l | d | \0 |
+----+ +----+----+----+----+----+----+
+-----------▲
here address of world string is first address = 93.
str1: value change to point string world.
Important to note:
str1
points to constant strings hence you can't modify string by accessing/indexing memory location for example str1[i] = 'A'
; will be illegal because you are writing on read only memory and behaviors of this is Undefined at runtime (although no compilation error because syntactically its correct).
Again because
str1
is a pointer sizeof(str1)
will give 4 on same machine.
My following code and its run:
#include <stdio.h>
int main(){
char* str1="Hello";
printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1));
str1 = "world";
printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1));
return 1;
}
Output:
str1: Hello, address: 0x80485e8, sizeof(str1): 4
str1: world, address: 0x8048619, sizeof(str1): 4
So, to assign new string I simply assign address of new string. But I can't call
strcpy()
that will try to write on read only memory location and that is illegal.
In second declaration
char str2[] = "hello";
, str2[]
is an \0
terminated array of chars (or string) but NOT pointer. Notice because in this declaration size is not given default size will we that size of constant string "hello" that is 6. Type of str2
is char[6]
.
When we do
char str2[] = "hello";
an array of char created and hello string will be copied into that array So str2
is not simply pointer but an array storing complete string.
Its conceptually in like.
str2:
103 104 105 106 107 108
+----+----+----+----+----+----+
| h | e | l | l | o | \0 |
+----+----+----+----+----+----+
And in this case lately in your code you are not allow to do
str2[] = "world";
or str2 = "world"
infect it will be compilation time error.
Example Code:
#include<stdio.h>
int main(){
char str2[] = "hello";
str2[] = "world";
str2 = "world";
return 1;
}
Compilation errors:
In function 'main':
Line 4: error: expected expression before ']' token
Line 5: error: incompatible types in assignment
Where this array
str2
is not constant, we can modify its content for example doing str2[2] = 'A'
is perfectly valid. We can also call strcpy to change content (and address space will not change) strcpy(str2, "world");
str2:
103 104 105 106 107 108
+----+----+----+----+----+----+
| w | o | r | l | d | \0 |
+----+----+----+----+----+----+
Note world coped into same memory space, address of world and hello
string is name.
Code Example:
#include<stdio.h>
int main(){
char str2[] = "hello";
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
str2[2] = 'A';
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
strcpy(str2, "world");
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
return 1;
}
Output:
str2: hello, address: 0xbf58d056, sizeof(str2): 6
str2: heAlo, address: 0xbf58d056, sizeof(str2): 6
str2: world, address: 0xbf58d056, sizeof(str2): 6
Note: string values are different on same address space.
sizeof(str2)
= 6 perfectly understood from older answer that is size of array in bytes.
To read similar description about 2-Dimensional array read: Difference between
char* str[]
andchar str[][]
and how both stores in memory?
0 comments:
Post a Comment
Don't Forget to comment