先看一个东西,
char *w;
w=(char *)malloc(20);
w="asdddddd";
printf("s=%s",w);
free(w);
malloc这个语句是没有效果的,他给w在栈中分配了20个字节,但是下一句就变了w的指向,就是“asdddddd
”的首地址。而字符串指针本来就可以直接指一个字符串的首地址。没有问题也不会出错1
这个很简单,但是在w指向asdddddd之后,就只可以读而不可以写了,因为像22,或者“adf”这种变量所在的地址是不属于指针的,因此是不可以写的。
比如:
char *str1=(char *)malloc(sizeof(char)*100);
str1="123456789";
puts(str1);
char *str2=(char *)malloc(sizeof(char)*100);
str2="abcdefg";
puts(str2);
strcpy(str2,str1);
puts(str1);
puts(str2);
这样写一个不属于指针的地址,自然就出错了。
在编程语言中,数据分为常量和变量,常量是只读的,变量是可读、可修改赋值的。char *StrConst= "123456789"; 是字符串常量,而数组char StrArray[]="123456789";是定义了一个字符串变量。不同的操作系统、不同的编译器对于常量和变量的处理措施是允许进行进行特有的优化、保护的。
解决方法,如上面的分析,可以用数组代替:
char *str1=(char *)malloc(sizeof(char)*100);
str1="123456789";
puts(str1);
char str3[100]="asdf";
strcpy(str3,str1);
puts(str1);
puts(str3);
这样是可以的。
还有就是定义一个字符串指针,分配地址(这一步必须的),之后就直接写入,不要让他再指向一个常量,这样他就是一个变量了,是可以写的。
char *str1=(char *)malloc(sizeof(char)*100);
str1="123456789";
puts(str1);
char *str2=(char *)malloc(sizeof(char)*100);
strcpy(str2,str1);
puts(str1);
puts(str2);
最后记得要free。
还有一个问题,就是在给指针分配一段地址空间以后,如果在指向一个常量,那么分配的空间是没有办法free的,可以看程序,他的运行结构就是异常。
int main(void)
{
char *str1=(char *)malloc(sizeof(char)*100);
str1="123456789";
puts(str1);
char *str2=(char *)malloc(sizeof(char)*100);
strcpy(str2,str1);
puts(str1);
puts(str2);
char *w;
w=(char *)malloc(20);
w="asdddddd";
printf("s=%s",w);
free(str1);
free(str1);
free(str2);
return 0;
}
当w和str1指向一个常量以后他们原来分配的空间就成了“无名地址”了,无法删除,free(w)和free(str1)都是要删了常量所指向的地址,常量也是不可以删除了,编译器会在常量作用完之后自己回收的,删除不了的!