memcpy,strcpy拷贝安全?
·
memcpy、strcpy 拷贝安全吗?
结论:都不安全!strcpy 和 memcpy 都是C语言标准库中不安全的内存拷贝函数,它们不会检查目标缓冲区大小,极易造成缓冲区溢出,导致程序崩溃、数据篡改、安全漏洞(黑客攻击)。
下面我给你讲清楚两者的区别、风险、以及正确的安全替代方案。
一、先搞懂两个函数的作用
1. strcpy —— 字符串拷贝
char* strcpy(char* dest, const char* src);
- 只用于字符串,遇到
\0才停止 - 不检查目标缓冲区大小
- 风险:源字符串过长 → 覆盖目标内存 → 缓冲区溢出
2. memcpy —— 内存块拷贝
void* memcpy(void* dest, const void* src, size_t n);
- 通用内存拷贝,不关心内容,不管
\0 - 必须手动指定拷贝长度
n - 风险:
n大于目标缓冲区大小 → 内存越界 → 崩溃/漏洞
二、为什么不安全?(核心风险)
1. 共同致命问题
✅ 都不验证目标缓冲区是否足够大
✅ 都可能导致内存越界写入
✅ 都是高危安全漏洞(CWE-120 缓冲区溢出)
2. 各自坑点
- strcpy 坑:依赖
\0结束,漏写\0会乱拷贝,且完全不限制长度 - memcpy 坑:长度由程序员手动控制,算错长度就直接越界
三、不安全代码示例(一看就懂)
1. strcpy 溢出
char buf[5]; // 只能存 4 个字符 + \0
strcpy(buf, "hello world"); // 超长!直接越界写内存
2. memcpy 溢出
char buf[5];
char data[] = "123456789";
memcpy(buf, data, 10); // 拷贝10字节 → 越界!
后果:程序崩溃、堆栈破坏、数据被篡改、远程代码执行漏洞。
四、安全替代函数(必须用这些!)
1. 字符串安全拷贝 → strncpy / snprintf
推荐:snprintf(最安全、最常用)
snprintf(dest, 目标缓冲区大小, "%s", src);
- 自动限制长度
- 一定会保证结尾加 \0
- 绝对不会溢出
示例:
char buf[5];
snprintf(buf, sizeof(buf), "%s", "hello world");
// 结果:buf = "hel\0"(安全截断)
2. 内存安全拷贝 → memmove / memcpy_s
memmove:比memcpy多支持内存重叠情况,更安全memcpy_s:C11 安全标准函数,强制检查长度、空指针
最通用安全写法:
memcpy(dest, src, 要拷贝的长度 <= 目标缓冲区大小 ? 要拷贝的长度 : 目标缓冲区大小);
五、快速对比表
| 函数 | 用途 | 安全吗 | 最大问题 |
|---|---|---|---|
strcpy |
字符串拷贝 | ❌ 不安全 | 不检查长度,溢出 |
memcpy |
内存拷贝 | ❌ 不安全 | 手动算长度,易越界 |
snprintf |
字符串拷贝 | ✅ 安全 | 自动截断,补 \0 |
memmove |
内存拷贝 | ✅ 较安全 | 支持内存重叠 |
strncpy |
字符串拷贝 | ⚠️ 半安全 | 可能不补 \0 |
总结
strcpy和memcpy都不安全,禁止在新项目中使用- 字符串拷贝用
snprintf(最安全) - 内存拷贝用
memmove或带长度校验的memcpy - 核心安全原则:拷贝前必须检查:目标缓冲区 ≥ 拷贝长度
更多推荐
所有评论(0)