C语言malloc分配1字节执行strcpy为何未触发段错误
原因解释
这是C语言里典型的未定义行为(Undefined Behavior, UB),代码没有触发段错误还能正常输出Vict只是当前运行环境下的偶然结果,不属于C标准保证的合法可稳定复现逻辑,具体原因可以拆解为三点:
- malloc的实际分配粒度远大于申请值
主流C标准库的malloc实现不会严格按传入的字节数返回精确大小的内存:为了满足内存对齐要求、降低内存碎片管理成本,malloc的最小分配单元通常是8字节或16字节。你申请1字节时,实际返回的内存块可用空间远大于1字节,拷贝5字节内容时还没超出这个实际分配块的边界,没有访问到非法地址。 - 段错误不是内存越界就必然触发
段错误是内核提供的内存保护机制,触发条件非常明确:只有进程访问了未映射到自身地址空间的内存地址,或者**对无对应权限的地址做操作(比如写只读的代码段)**时才会抛出段错误。如果越界写入的位置刚好是malloc预留的对齐填充字节、相邻的空闲内存块这类已经归属进程可写范围的地址,内核完全感知不到越界操作,自然不会触发异常。 - strcpy本身不带缓冲区长度校验
strcpy不会检查目标缓冲区的可用长度,只会逐字节拷贝源字符串直到遇到\0结束符。只要拷贝路径上的所有地址都是可写状态,拷贝操作就能正常完成;后续printf读字符串也是逐字节遍历直到\0,只要这段内存里的字符串内容没被破坏,就能正常输出结果。
这种写法有极高的内存安全隐患,本次运行正常纯粹是运气好。如果越界写入的位置刚好覆盖了malloc维护的内存块元数据,后续调用
free/malloc时就会触发崩溃;如果越界位置刚好是其他变量的存储区域,会导致随机出现的逻辑错误,这类问题排查成本极高。绝对不要在可交付代码中依赖这种偶然的运行结果。
内容的提问来源于stack exchange,提问作者v1d3rm3
相关产品推荐
相关产品推荐

