fill_n vs memset 设置数组的默认值

fill_n vs memset to set default value of an array

我想知道如果你想用默认值 n 填充数组,理想的方法是什么:

#include <cstring> // for memset
#include <algorithm> // for fill_n

static constexpr int N = 100;
int a[N];
static constexpr int defaultValue = -1;

void* memset( void* dest, int ch, std::size_t count );

memset(a, defaultValue, sizeof(a));

(memset) converts the value ch to unsigned char and copies it into each of the first count characters of the object pointed to by dest. If the object is a potentially-overlapping subobject or is not TriviallyCopyable (e.g., scalar, C-compatible struct, or an array of trivially copyable type), the behavior is undefined. If count is greater than the size of the object pointed to by dest, the behavior is undefined.

constexpr OutputIt fill_n( OutputIt first, Size count, const T& value );

fill_n(a, N, defaultValue);

(fill_n) assigns the given value to the first count elements in the range beginning at first if count > 0. Does nothing otherwise.

我正在寻找见解,我当然知道如何阅读文档!

编辑:默认值可能不只是 -1。

这两个函数做不同的事情。当然,它们填充了一块内存,但是它们填充的方式完全不同。

memset 在字节级操作。 defaultValue 被分解为 unsigned char,因此大于单个字节的 defaultValue 被缩减到一定大小,信息丢失。现在字节大小的值单独应用于每个字节,而不是数组中的每个 int。在 -1 的情况下,你得到“幸运”,因为 0xFF 的四个字节看起来相同,0xFFFFFFFF,作为 32 位整数世界中的二进制补码 -1。大多数其他数字都没有这样的运气。 1,例如,不会导致一个充满int的数组被设置为1,它被填充为0x01010101,或者16843009.

fill_n 另一方面,尊重数组元素的类型。数组中的每个 int 都将设置为 defaultValue。在 defaultValue 为 1 的情况下,数组将充满 1。 defaultValue of 256,提供一个全256的数组。

就速度而言,这可能无关紧要。如今,以字节为单位读取或写入的内存很少见。一次写入整个 ints 可能会更快。但是一个好的 memset 实现知道这一点并且会利用它。如果没有,编译器可能会。