C语言字符串追加报错求助:罗马数字转换内存访问冲突问题
解决C语言字符串追加的访问冲突问题(模拟C#的
+=操作) 错误原因分析
- 未初始化malloc分配的内存:
malloc(1000)仅分配内存空间,不会初始化内容,里面是随机垃圾数据。strcat要求目标字符串必须以'\0'(字符串结束符)结尾,否则会从起始位置持续查找结束符,越界访问非法内存,触发Access violation错误。 - 多余且错误的
strcpy操作:strcat本身就会把源字符串追加到目标末尾,且返回目标字符串指针。你写的strcpy(onesString, strcat(onesString, "I"))相当于把修改后的onesString复制给自己,完全没必要,还可能引发内存操作冲突。 - 分支覆盖不全:当
ones为1、2、3时,前面的if/else if分支都不执行,onesString仍处于未初始化状态,直接进入循环调用strcat必然出错。
可行解决方法
- 分配内存后立即初始化字符串为空:用
strcpy(onesString, "")或直接给第一个字节赋值*onesString = '\0',确保字符串有合法结束符。 - 直接用
strcat完成追加:不需要嵌套strcpy,strcat(onesString, "I")就能直接把"I"追加到onesString末尾,和C#里的onesString += "I"效果一致。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> char * ToRomanNumeral(int integer) { if (integer > 10) { return "Not implemented"; } int ones = integer % 10; // 分配内存后立即初始化为空字符串,同时检查malloc是否成功 char * onesString = malloc(1000); if (onesString == NULL) { return NULL; } strcpy(onesString, ""); // 生成个位数罗马数字 if (ones == 9) { strcpy(onesString, "IX"); } else if (ones >= 5) { strcpy(onesString, "V"); // 追加剩余的I,比如ones=6对应V+I for (int i = 0; i < ones - 5; i++) { strcat(onesString, "I"); } } else if (ones == 4) { strcpy(onesString, "IV"); } else { // 处理ones为0、1、2、3的情况 for (int i = 0; i < ones; i++) { strcat(onesString, "I"); } } return onesString; } int main() { printf("Hello, World!\n"); char *roman = ToRomanNumeral(1); if (roman != NULL) { printf("%s\n", roman); free(roman); // 释放malloc分配的内存,避免泄漏 } return 0; }
额外注意点
- 调用
malloc后必须检查返回值是否为NULL,避免内存分配失败导致后续操作出错。 - 主函数中使用完返回的字符串后,要调用
free释放内存,否则会造成内存泄漏。 - 不能返回栈上数组(比如
char onesString[] = "")的指针,因为栈内存会在函数结束后被释放,调用者访问会触发未定义行为;char *onesString = ""指向只读字符串常量,无法修改,所以strcat会报错。
内容的提问来源于stack exchange,提问作者What HelpMe HelpMe
相关产品推荐
相关产品推荐

