C语言拼接字符串时前缀出现随机乱码字符的问题咨询
问题根因
- 两次字符串拼接的目标数组都未初始化,
strcat函数要求目标参数必须是合法的、以'\0'结尾的C字符串,函数会从目标字符串的'\0'位置开始拼接新内容。你定义的局部栈数组未做初始化,内存存储的是随机垃圾值,strcat会从随机位置的'\0'开始写入,最终打印就会出现开头的随机异常字符。第一次拼接conc时看起来正常属于巧合,刚好栈上分配的conc数组首字节是随机的'\0',第二次分配的phrase数组内存开头没有随机'\0',问题就暴露了,这就是两次拼接表现不一致的原因。 conc数组长度计算错误:拼接内容为str2 + 空格 + str3 + 结束符,总长度应为len2 + 1 + len3 + 1 = len2 + len3 + 2,你当前只开了catLen +1 = len2 + len3 +1,少了1个字节,会发生数组越界,触发未定义行为。- 从管道读取的
str1存在两个问题:一是长度未预留结束符位置,二是读取完成后未手动补'\0',read系统调用只会按指定长度读取字节,不会自动加字符串结束符,导致str1不是合法的C字符串,直接传给printf或strcat都会出现乱码或越界;另外读取str1时多写了取地址符&,str1本身就是数组首地址,加&会导致读取地址错误。 phrase数组长度不足:拼接内容为str1 + 空格 + conc + 结束符,总长度应为len1 +1 + strlen(conc) +1 = len1 + len2 + len3 +3,你当前开的长度只有len1 + catLen +1 = len1 + len2 + len3 +1,少了2个字节,也会触发越界。
修复方案
修改后的代码如下,核心修改点已标注:
char* str2 = argv[2]; int len2 = strlen(str2); char* str3 = argv[3]; int len3 = strlen(str3); printf("child PID(%d) receives Y = '%s' and Z= '%s' from the pipe\n",getpid(), str2, str3 ); // 修改1:conc数组长度+2,预留空格和结束符位置 int catLen = len2+len3; char conc[catLen + 2]; // 修改2:初始化目标数组为空字符串,满足strcat要求 conc[0] = '\0'; strcat(conc, str2); strcat(conc," "); strcat(conc, str3); printf("child PID(%d) concatenates Y and Z to generate Y' = '%s'\n",getpid(),conc); int len1; read(port[0],&len1,sizeof(len1)); // 修改3:str1长度+1,预留结束符位置 char str1[len1 + 1]; // 修改4:去掉多余的&,str1本身就是首地址 read(port[0], str1,len1); // 修改5:手动补字符串结束符 str1[len1] = '\0'; printf("child PID(%d) reads X from the pipe = '%s'\n",getpid(),str1); // 修改6:phrase数组长度+3,预留空格、conc结束符、新结束符位置 int totalLen = len1+catLen+3; char phrase[totalLen]; // 修改7:初始化目标数组为空字符串 phrase[0] = '\0'; strcat(phrase, str1); printf("%s\n",phrase); strcat(phrase," "); printf("%s\n",phrase); strcat(phrase,conc); printf("child PID(%d) concatenates X and Y' to generate Z' = '%s'\n",getpid(),phrase);
内容的提问来源于stack exchange,提问作者Marco Aiello
相关产品推荐
相关产品推荐

