C++ —— memset、memcpy、std::copy函数
memset()
功能
将一段连续内存
中的每个字节
都设置
为同一个值
,常用于初始化
数组或结构体的内存。
函数原型
void *memset(void *s, int c, size_t n);
s
:指向要设置的内存块的指针
c
:要设置的值(以无符号字符的形式传递)
n
:要设置的字节数
示例代码
#include <cstring>
#include <iostream>
int main() {
char buffer[10];
// 将 buffer 中的所有字节设置为 0
memset(buffer, 0, sizeof(buffer));
// 输出每个字节的值
for (int i = 0; i < 10; ++i) {
std::cout << static_cast<int>(buffer[i]) << " ";
}
std::cout << std::endl;
return 0;
}
memcpy()
功能
将一块内存区域
的数据复制
到另一块内存区域
。它适用于复制原始内存
数据。memcpy()
最初是作为C
标准库的一部分定义的,其声明位于头文件<string.h>
中。在C++
中,可以通过包含头文件<cstring>
来使用memcpy()
。
函数原型
void *memcpy(void *dest, const void *src, size_t n);
dest
:目标内存块的指针
src
:源内存块的指针
n
:要复制的字节数
示例代码
#include <cstring>
#include <iostream>
int main() {
int src[5] = {1, 2, 3, 4, 5};
int dest[5];
// 将 src 数组中的所有字节复制到 dest 数组中
memcpy(dest, src, sizeof(src));
// 输出复制后的结果
for (int i = 0; i < 5; ++i) {
std::cout << dest[i] << " ";
}
std::cout << std::endl;
return 0;
}
注意事项
- 浅拷贝:
memcpy()
仅仅是按字节
复制数据,对于包含指针
或需要深拷贝
的对象不适用。对于非POD
类型(Plain Old Data)的对象,应该使用其拷贝构造函数
或赋值运算符
。 - 内存重叠问题:如果
源
和目标内存
区域重叠
,memcpy()
的行为是未定义的
。这种情况下应使用memmove()
。
std::copy()
功能
std::copy()
是C++
标准库中的算法,定义在<algorithm>
头文件中。它可以复制
一个区间内的元素到另一个区间
,能够根据元素类型自动调用拷贝构造函数,适用于各种数据容器
和迭代器
。
函数原型
template <class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);
first
:待复制区间的起始迭代器
last
:待复制区间的结束迭代器
result
:目标区间的起始迭代器
示例代码
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> src = {1, 2, 3, 4, 5};
std::vector<int> dest(src.size());
// 使用 std::copy() 复制 vector 中的元素
std::copy(src.begin(), src.end(), dest.begin());
// 输出复制后的结果
for (auto v : dest) {
std::cout << v << " ";
}
std::cout << std::endl;
return 0;
}
注意事项
- 类型安全:
std::copy()
能够处理任意类型
的对象,不会像memcpy()
那样直接进行字节级复制,对于复杂类型
会调用
对象的拷贝构造函数
。 - 灵活性:它依赖于迭代器,因此可以用于 STL 容器、原生数组以及任何支持迭代器的对象。
- 安全性:相比于
memcpy()
,std::copy()
能够正确处理元素类型的复制,更符合C++
的面向对象
编程理念。