C语言使用strcat函数拼接字符串得到空字符串是什么原因?
问题根本原因
你的代码存在两处核心错误,共同导致了未定义行为,最终出现空字符串的异常结果:
- 覆盖了malloc申请的堆内存地址
你首先用malloc给dest分配了20字节的可写堆内存,但是后续执行dest = "Hello"时,直接修改了dest指针本身的指向,让它指向了存储在只读常量区的字符串"Hello",不仅丢失了malloc申请的内存地址造成内存泄漏,还让后续操作的目标变成了不可写的常量内存。 - 对只读内存执行写操作
strcat的工作逻辑是把第二个参数的字符串内容追加到第一个参数指向的字符串末尾,会修改第一个参数指向的内存内容。而你传入的dest此时指向只读常量区,对该区域执行写入属于C语言标准规定的未定义行为,不同编译器、不同运行环境可能出现崩溃、乱码、空字符串等任意异常结果。
正确修复方案
不要直接给dest指针赋值字符串常量,改用strcpy把"Hello"的内容复制到你之前malloc申请的可写堆内存中,修复后的代码如下:
#include <string.h> #include <stdio.h> #include <stdlib.h> int main(void) { char *dest = (char*) malloc(sizeof(char) * 20); char *src = "World"; // 将Hello复制到malloc申请的可写内存中 strcpy(dest, "Hello"); printf("%s", strcat(dest, src)); // 输出HelloWorld free(dest); // 释放堆内存,避免泄漏 return 0; }
额外注意事项
strcat要求第一个参数指向的内存必须同时满足三个条件:可写、有足够的剩余空间容纳拼接后的字符串、末尾存在'\0'结束符- 如果需要给char指针指向的内存写入字符串内容,不要直接用
=赋值,要使用strcpy/strncpy等字符串操作函数完成内容拷贝 - 动态申请的内存使用完成后必须调用
free释放,避免出现内存泄漏
内容的提问来源于stack exchange,提问作者Emmanuel Canto Vázquez
相关产品推荐
相关产品推荐

