#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *str = (char*)malloc(4);
strcpy(str,"aaab");
char *pt;
strcpy(pt,str);
while(pt != NULL){
printf("%c",*pt);
pt++;
}
}
我希望这段代码只打印出 str 字符串,但它却给了我字符串和一些奇怪的输出。随着模式的不断变化,事情变得更好了。我认为问题在于空字符
'\0'
终止。
显示的代码有几个问题。
第一个是字符串文字
"aaab"
包含5
字符(包括终止零字符'\0'
)而不是4
。所以 strcpy
的调用期望作为第二个参数指向字符串
char *str = (char*)malloc(4);
strcpy(str,"aaab");
调用未定义的行为,因为目标动态分配的内存不够大,无法存储
5
字符。
需要多分配一个字节来存放字符串
char *str = (char*)malloc(5);
在此代码片段中
char *pt;
strcpy(pt,str);
使用了未初始化的指针
pt
,结果再次调用strcpy
调用未定义的行为。
而这个 while 循环有未定义的行为,即使指针
pt
会被初始化
while(pt != NULL){
printf("%c",*pt);
pt++;
}
相反,您不应该将指针本身与
NULL
进行比较,而应该将指针指向的字符与终止零字符 '\0'
进行比较,例如
while(*pt != NULL){
printf("%c",*pt);
pt++;
}
当然指针
pt
应该指向一个字符串。
strcpy(str,"aaab")
char *ptr;
这只为指针分配了内存。指针的内容是不确定的,即它们可能指向任何东西并且访问指针指向的内存会调用未定义的行为。在尝试将某些内容复制到它之前,您需要先为指向的数据分配内存。
不要投
malloc()
的结果。 malloc()
和 family 返回一个通用的 void *
,它被隐式转换为任何其他指针类型。转换是多余的,只会使代码混乱。
检查
malloc()
的返回值。它返回一个 NULL
指针常量以指示失败。
像这样使用
malloc(4);
时,它只提供4个字节,但对于字符至少需要多一个字节。
所以我建议使用
char *str = (char*)malloc(5);
但更可靠的解决方案是计算源字符串的长度,将此值加1并为目标字符串分配内存。例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *s1 = "aaab";
char *s2 = (char*)malloc(strlen(s1) + 1);
strcpy(s2, s1);
printf(">%s<", s2);
}