所以sizeof(str1)=sizeof(char*)=4,在C/C++中一个指针占4个字节 str2是一个字符型数组。C/C++规定,对于一个数组,返回这个数组占的总空间,所以sizeof(str2)取得的是字符串"absde"占的总空间。
"absde"中,共有a b s d e \0六个字符,
所以str2数组的长度是6,所以sizeof(str2)=6*sizeof(char)=6 str3已经定义成了长度是8的数组,所以sizeof(str3)为8 str4和str2类似,'0' '1' ... '9'加上'\0'共11个字符,所以ss占的空间是8 总之,对于指针,sizeof操作符返回这个指针占的空间,一般是4个字节(32位系统);而对于一个数组,
sizeof返回这个数组所有元素占的总空间。char*与char[]容易混淆,一定要分清,而且char*="aaa"的写法现在不被提倡,应予以避免 而strlen不区分是数组还是指针,就读到\0为止返回长度。而且strlen是不把\0计入字符串的长度的。
这里前面都对的,但对于64位系统,这个指针是占8个字节。
将这个程序再改改比较下;
#include
int main(void){
char * str1="abcde";
char str2[]="abcde";
char str3[8]={'a',};
char ss[]="0123456789";
printf("sizeof(str1)=%ld ",sizeof(str1));
printf("sizeof(str2)=%ld ",sizeof(str2));
printf("sizeof(str3)=%ld ",sizeof(str3));
printf("sizeof(ss)=%ld\n",sizeof(ss));
printf("strlen(str1)=%d,strlen(str2)=%d,strlen(str3)=%d,strlen(ss)=%d\n",
strlen(str1), strlen(str2), strlen(str3), strlen(ss));
return 0;
}
sizeof(str1)=8 sizeof(str2)=6 sizeof(str3)=8 sizeof(ss)=11
strlen(str1)=5,strlen(str2)=5,strlen(str3)=1,strlen(ss)=10
还有点需要特别提醒,字符串在初始化时尽量不要指定大小,或者在指定时要考虑'\0'这个NULL结束符
所占的一个空间,否则可能读取时超出界限,引出异常。如将上面的ss再改动下;
#include
int main(void){
char * str1="abcde";
char str2[]="abcde";
char str3[8]={'a',};
char ss[10]="0123456789";
printf("sizeof(str1)=%ld ",sizeof(str1));
printf("sizeof(str2)=%ld ",sizeof(str2));
printf("sizeof(str3)=%ld ",sizeof(str3));
printf("sizeof(ss)=%ld\n",sizeof(ss));
printf("strlen(str1)=%d,strlen(str2)=%d,strlen(str3)=%d,strlen(ss)=%d\n",
strlen(str1), strlen(str2), strlen(str3), strlen(ss));
return 0;
}
sizeof(str1)=8 sizeof(str2)=6 sizeof(str3)=8 sizeof(ss)=10
strlen(str1)=5,strlen(str2)=5,strlen(str3)=1,strlen(ss)=11
这结果刚好反了,如果在不同的机器,不同时间这个strlen可能又有不同。。。
有了上面的认识再来看一个程序,是linux环境下c编程书上的一个例子。本意是解决
内存溢出的实例:
#include
#include
void upcase(char *inputstring,char *newstring);
int main(void)
{
char str1[4];
upcase("Hello",str1);
printf("str1=%s\n",str1);
return 0;
}
void upcase(char *inputstring,char *newstring)
{
int counter;
strncpy(newstring,inputstring,sizeof(newstring)-1);
for(counter=0;counter
if(newstring[counter]>=97 && newstring[counter]<=122)
newstring[counter]-=32;
}
*(newstring+strlen(newstring)) = 0x00;
return newstring;
}
这个例子在32位系统上跑起来应该没有问题,初看起来也很正确;但你稍稍变化下str1初始大小比如12,改动下字符串如。hello,world之类的,就会发现结果完全不对。。
这里关键是sizeof(newstring),这里实际是对指针变量取sizeof,在我64位机上结果会永远为8,32位为4;这样明显偏离了原意。。还有最后的 *(newstring+strlen(newstring)) = 0x00;strcpy函数在目的空间足够情况下会将空闲空间填为'\0', 可用man 3 strcpy查看下帮助,了解;实际这步在前面已经减1情况下是多余的操作。。。解决方案,自己思考下吧。。~+~