You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio中strcpy_s的异常行为及-2值来源探究

关于strcpy_s行为与-2值来源的解析

环境与测试代码

平台:Win11、Visual Studio 2022

测试代码:

#include <stdio.h>
#include <string.h>

int main()
{
    char ori[5] = { 'a', 'b', '\0', 'c', 'd' };
    //char *safe = malloc(10 * sizeof(char));
    //char *unsafe = malloc(10 * sizeof(char));

    char safe[10];
    char unsafe[10];
    memset(safe, 0, 10 * sizeof(char));
    memset(unsafe, 0, 10 * sizeof(char));
    strcpy(unsafe, ori);
    strcpy_s(safe, 10, ori);
    printf("SAFE: %c\n", safe[3]);
    printf("UnSafe: %c\n", unsafe[3]);

    return 0;
}

问题现象

初始化后safe和unsafe数组均为全0,执行strcpy和strcpy_s后,预期两个数组都会变成{'a','b','\0','\0','\0','\0','\0','\0','\0','\0'},但实际safe数组为{97,98,0,-2,-2,-2,-2,-2,-2,-2}。

strcpy_s的具体行为

strcpy_s是C标准库为提升安全性设计的字符串拷贝函数,相比strcpy多了两项关键操作:

  1. 校验目标缓冲区长度是否足够容纳源字符串(含终止符\0),长度不足时会触发错误处理(默认可能直接终止程序,取决于编译器设置)。
  2. 源字符串拷贝完成后,会将目标缓冲区剩余未使用的字节填充为特定“毒药值”——这是Visual Studio实现的特性,用于辅助开发者检测内存越界访问或未初始化内存的使用问题。

-2值的来源

你看到的-2对应十六进制0xFE,是微软编译器定义的毒药值。这个值用来标记“已初始化但未被正常使用的内存”,目的是让开发者在调试时快速发现异常:如果程序意外访问到这些填充值,就能立刻意识到可能存在逻辑漏洞。

在你的测试中,ori含终止符共占3字节,safe缓冲区长度为10字节,拷贝完成后剩余的7字节(索引3到9)就被填充为0xFE(十进制-2)。而strcpy没有填充逻辑,剩余字节保持初始的0值。

内容的提问来源于stack exchange,提问作者Zhou Jia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:52:48