sizeof和strlen运用在字符串中时较容易混淆,现以一个简单的例子来说明。
#include<stdio.h>
#include<string.h>
int main()
{
char a[7] = {'a','b','c','d','e','f','g'};
char b[7] = {'a','b','c','d','e','f'};
char c[7] = {'a','b'};
char d[7] = {'a','b','\0'};
char e[] = "abcdefg";
char f[7] = {'a','b','c','d','e','f','g'};
char *p = "abcdefg";
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(a),strlen(a),a);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(b),strlen(b),b);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(c),strlen(c),c);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(d),strlen(d),d);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(e),strlen(e),e);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(f),strlen(f),f);
printf("\r\nsizeof=%d,strlen=%d,addr=%p\r\n",sizeof(p),strlen(p),p);
return 0;
}
sizeof计算的是符号类型长度。其中a ,b, c, d, f 数组的分配的都是7个字节所以sizeof() 均为7。而e是一个没有确定长度的数组地址,所以看其指向的字符串的长度,注意字符串最后有\0, 故sizeof(e)是8。p不是数组是指针, 长度与测试环境有关,例如本实验的linux是32位,sizeof(p)=4,如果实验的linux是64位的,那sizeof(p)=8。
strlen计算的是字符串的长度。所以在计算字符串长度的时候,要计算到'\0'但不包括'\0'。数组a长度是7,字符也是7个,没有结束符,所以strlen(a)不确定,但是数组a、b在栈上是连续的而b最后有'\0' 所以strlen(a)=7+6=13。strlen(b)=6, 如果b[6] != 0那就又不好确定了,说明了memset 0的重要性,当然本例是在初始化的时候默认是0了。strlen(c)=2。 strlen(d)=2。strlen(e)=7。strlen(f)这个和strlen(a)相似,不同的是,不确定f[7]地址处是否是0,在栈空间上地址后续连的是那个符号存的值,试验结果从栈上看f在e前面所以 strlen(f)=7+7=14。strlen(p) = 7。
下面是试验结果,gdb查看的栈空间数据。
(gdb) r
Starting program: /home/io/a.out
sizeof=7,strlen=13,addr=0xbffff5a1
sizeof=7,strlen=6,addr=0xbffff5a8
sizeof=7,strlen=2,addr=0xbffff5af
sizeof=7,strlen=2,addr=0xbffff5b6
sizeof=8,strlen=7,addr=0xbffff5c4
sizeof=7,strlen=14,addr=0xbffff5bd
sizeof=4,strlen=7,addr=0x8048700
Breakpoint 1, main () at 3.c:22
22 return 0;
(gdb) p &f
$1 = (char (*)[7]) 0xbffff5bd
(gdb) x/32cb &f
0xbffff5bd: 97 'a' 98 'b' 99 'c' 100 'd' 101 'e' 102 'f' 103 'g' 97 'a'
0xbffff5c5: 98 'b' 99 'c' 100 'd' 101 'e' 102 'f' 103 'g' 0 '\000' 0 '\000'
0xbffff5cd: -117 '\213' 27 '\033' 90 'Z' -36 '\334' -109 '\223' -5 '\373' -73 '\267' -16 '\360'
0xbffff5d5: -11 '\365' -1 '\377' -65 '\277' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 71 'G'
(gdb) x/32xb &f
0xbffff5bd: 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x61
0xbffff5c5: 0x62 0x63 0x64 0x65 0x66 0x67 0x00 0x00
0xbffff5cd: 0x8b 0x1b 0x5a 0xdc 0x93 0xfb 0xb7 0xf0
0xbffff5d5: 0xf5 0xff 0xbf 0x00 0x00 0x00 0x00 0x47
(gdb) x/64xb &a
0xbffff5a1: 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x61
0xbffff5a9: 0x62 0x63 0x64 0x65 0x66 0x00 0x61 0x62
0xbffff5b1: 0x00 0x00 0x00 0x00 0x00 0x61 0x62 0x00
0xbffff5b9: 0x00 0x00 0x00 0x00 0x61 0x62 0x63 0x64
0xbffff5c1: 0x65 0x66 0x67 0x61 0x62 0x63 0x64 0x65
0xbffff5c9: 0x66 0x67 0x00 0x00 0x8b 0x1b 0x5a 0xdc
0xbffff5d1: 0x93 0xfb 0xb7 0xf0 0xf5 0xff 0xbf 0x00
0xbffff5d9: 0x00 0x00 0x00 0x47 0xe6 0xe1 0xb7 0x00
(gdb) x/64cb &a
0xbffff5a1: 97 'a' 98 'b' 99 'c' 100 'd' 101 'e' 102 'f' 103 'g' 97 'a'
0xbffff5a9: 98 'b' 99 'c' 100 'd' 101 'e' 102 'f' 0 '\000' 97 'a' 98 'b'
0xbffff5b1: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 0 '\000' 97 'a' 98 'b' 0 '\000'
0xbffff5b9: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 97 'a' 98 'b' 99 'c' 100 'd'
0xbffff5c1: 101 'e' 102 'f' 103 'g' 97 'a' 98 'b' 99 'c' 100 'd' 101 'e'
0xbffff5c9: 102 'f' 103 'g' 0 '\000' 0 '\000' -117 '\213' 27 '\033' 90 'Z' -36 '\334'
0xbffff5d1: -109 '\223' -5 '\373' -73 '\267' -16 '\360' -11 '\365' -1 '\377' -65 '\277' 0 '\000'
0xbffff5d9: 0 '\000' 0 '\000' 0 '\000' 71 'G' -26 '\346' -31 '\341' -73 '\267' 0 '\000'
(gdb) x/32cb p
0x8048700: 97 'a' 98 'b' 99 'c' 100 'd' 101 'e' 102 'f' 103 'g' 0 '\000'
0x8048708: 13 '\r' 10 '\n' 115 's' 105 'i' 122 'z' 101 'e' 111 'o' 102 'f'
0x8048710: 61 '=' 37 '%' 100 'd' 44 ',' 115 's' 116 't' 114 'r' 108 'l'
0x8048718: 101 'e' 110 'n' 61 '=' 37 '%' 100 'd' 44 ',' 97 'a' 100 'd'
(gdb) x/32xb p
0x8048700: 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x00
0x8048708: 0x0d 0x0a 0x73 0x69 0x7a 0x65 0x6f 0x66
0x8048710: 0x3d 0x25 0x64 0x2c 0x73 0x74 0x72 0x6c
0x8048718: 0x65 0x6e 0x3d 0x25 0x64 0x2c 0x61 0x64