仅malloc 1字节char未触发段错误?C语言strcat使用疑问
关于strcat和内存越界的问题解析
为什么你的代码没报错却能运行?
这是典型的未定义行为——C语言标准并不强制程序在内存越界时立刻报错,操作系统的内存保护也不是逐字节检查的。你的代码存在两个致命问题:
malloc(sizeof(char))仅分配1字节内存,但strcat要求目标缓冲区必须能容纳拼接后的完整字符串(包括末尾的'\0'),而"string!"加上终止符需要8字节空间,缓冲区完全不足。strcat的第一个参数必须指向以'\0'结尾的字符串,但malloc分配的内存是未初始化的,内部值随机,strcat会从concat开始盲目寻找'\0',这已经属于非法内存访问,只是刚好没触发崩溃。
为什么能访问*(concat +1232)?
依旧是未定义行为。操作系统的内存管理通常以“页”为单位(比如4KB一页),只要你访问的地址仍在当前进程的地址空间内,且未触及受保护的内存页,就不会立刻触发错误。但这种访问完全非法,可能会覆盖其他变量的数据,导致程序后续崩溃或出现诡异问题,只是当前没显现而已。
正确的用法示例
使用strcat必须满足两个前置条件:目标缓冲区足够大、初始化为以'\0'结尾的字符串。示例代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[]){ char string[] = "string!"; // 计算所需内存:字符串长度 + 1(用于末尾的'\0') size_t needed_size = strlen(string) + 1; char* concat = malloc(needed_size); if (concat == NULL) { // 必须检查malloc是否成功 perror("malloc failed"); return 1; } // 初始化concat为空字符串,让strcat找到正确的起始拼接位置 concat[0] = '\0'; strcat(concat, string); printf("%s\n", concat); free(concat); }
总结
你对strcat的核心功能理解没错,但忽略了它的前置要求。你的代码属于未定义行为,“运行正常”只是巧合,绝对不能这么写——未定义行为的结果不可预测,今天正常运行的代码,明天可能突然崩溃,甚至破坏程序其他部分的数据。
内容的提问来源于stack exchange,提问作者Cardinal
相关产品推荐
相关产品推荐

