能否未分配内存就用strcpy复制char*字符串?两种方案正误辨析
关于char*字符串独立复制的问题解答
首先明确结论:绝对不能不分配目标内存就用strcpy完成独立字符串的复制。strcpy的工作逻辑是把源字符串的内容(包括末尾的'\0'终止符)逐字节写入目标指针指向的内存区域,如果目标指针没有指向一块足够大的、可写的合法内存,会直接触发「未定义行为」——小则程序输出乱码,大则直接崩溃,甚至破坏其他内存里的数据。
接下来逐个分析你给出的两个方案:
Option 1 完全错误
//char *string_1 is already allocated and contains a valid string char *string_2; strcpy(string_1, string_2); printf("%s", string_2);
这里有两个致命问题:
string_2是未初始化的野指针,它指向的内存地址完全随机,根本不是你能合法读写的空间。- 你搞反了
strcpy的参数顺序!strcpy的第一个参数是目标内存,第二个才是源字符串,你现在是试图把随机野指针的内容复制到string_1,不仅没完成复制需求,还会破坏string_1原本的内容,同时触发未定义行为。
Option 2 同样错误
//char *string_1 is already allocated and contains a valid string char *string_2; string_2 = malloc(((int) strlen(string_1)) * sizeof(char)); strcpy(string_1, string_2); printf("%s", string_2);
这个方案虽然尝试分配内存,但还是犯了两个关键错误:
- 内存分配的大小不够:
strlen(string_1)返回的是字符串的有效长度,不包含末尾的'\0'终止符,所以你需要分配strlen(string_1) + 1个char的空间,否则复制后的字符串没有终止符,后续printf会读取到内存里的垃圾数据。 - 依然搞反了
strcpy的参数!应该是把string_1的内容复制到string_2,也就是strcpy(string_2, string_1),现在的写法还是在往string_1里写随机数据,完全达不到你的需求。
正确的做法示例
// 假设string_1已经是合法的、带终止符的字符串 char *string_2 = malloc(strlen(string_1) + 1); if (string_2 == NULL) { // 处理内存分配失败的情况,比如打印错误、退出程序 perror("malloc failed"); exit(EXIT_FAILURE); } strcpy(string_2, string_1); // 现在两个字符串是独立的,释放string_1不影响string_2 printf("%s", string_2); // 用完记得释放内存 free(string_2);
如果你用的是POSIX兼容的系统(比如Linux、macOS),也可以用strdup函数一步完成分配+复制:
char *string_2 = strdup(string_1); if (string_2 == NULL) { perror("strdup failed"); exit(EXIT_FAILURE); } // 同样,string_2是独立的副本
不过要注意strdup不是C标准库函数,是POSIX扩展,如果你写的是跨平台的标准C代码,还是用前面的malloc+strcpy更稳妥。
内容的提问来源于stack exchange,提问作者user157629
相关产品推荐
相关产品推荐

