如何清空C++数组?

25

如何清空/清除C++数组?有array::fill,但似乎只适用于C++11?我正在使用VC++ 2010。 如何将其清空(重置为全部0)?


1
重置所有为0并不等同于清空。 - leftaroundabout
1
@MichaelKrelin-hacker 对,我应该表达为“一个数组永远不能被清空”。 - juanchopanza
1
@juanchopanza 更普遍地说:数组的大小永远不能被更改。(清空只是更一般规则的特殊情况。)当然,由于没有情况需要动态分配一个数组,所以可以说数组永远不可能为空。 - James Kanze
好的,我的意思是将所有值都设置为零。那么你对清空数组有什么理解? - Jiew Meng
@JiewMeng,零元素也是一个元素。空数组不包含任何东西,甚至不包括零个元素。 - Michael Krelin - hacker
显示剩余5条评论
7个回答

38
std::fill_n(array, elementCount, 0);

假设 array 是一个普通数组(例如 int[]


6
C++11标准引入的类型array<T, N>拥有一个fill(Value)成员函数,可以用来填充数组。底层实现可能使用memset函数。 - Kemin Zhou

12
假设有一个大小为N的C风格数组a,其元素类型可以隐式转换自0,以下代码将所有元素设置为从0构造的值。
std::fill(a, a+N, 0);

请注意,这与“清空”或“清除”是不同的。
编辑:根据James Kanze的建议,在C++11中,您可以使用更惯用的替代方法。
std::fill( std::begin( a ), std::end( a ), 0 );

如果没有C++11,你可以按照以下方式自己解决:

template <typename T, std::size_t N> T* end_(T(&arr)[N]) { return arr + N; }

template <typename T, std::size_t N> T* begin_(T(&arr)[N]) { return arr; }

std::fill( begin_( a ), end_( a ), 0 );

在C++11中,您还可以编写std :: fill(std :: begin(a),std :: end(a),0)。不知何故,这似乎更符合惯用法。(有没有人在使用C++11之前的版本时没有类似的工具包?) - James Kanze
@MichaelKrelin-hacker,我的理解是将其设置为默认值,那么对于int来说,它的默认值是0?好吧,也许这不是正确的词语。但我想知道它实际上是什么意思。 - Jiew Meng
@JamesKanze 同意,但由于OP暗示C++11超出了范围,我提供了不太优雅的解决方案。我将添加一些(未经完全测试的)自制解决方案。 - juanchopanza
@JiewMeng,你可以在你的问题中更清楚地表达。请注意,你甚至没有提到你的数组存储的是“整数”! - juanchopanza

8
std::fill(a.begin(),a.end(),0);

0

for (auto& a : SomeArray) a = 0;

对于(自动引用 a :SomeArray)a = 0;


0

如果你想用除了内置值以外的东西来填充数组,std::fill 就不够用了;相反,我发现 std::generate 很有用。例如,我有一个列表向量需要初始化。

std::generate(v.begin(), v.end(), [] () { return std::list<X>(); });

你也可以使用整数,例如:

std::generate(v.begin(), v.end(), [n = 0] () mutable { return n++; });

或者只是

std::generate(v.begin(), v.end(), [] (){ return 0; });

但我想对于最简单的情况,std::fill更快


-1

如果只是归零,你可以使用memset

int* a = new int[6];

memset(a, 0, 6*sizeof(int));

3
请不要使用memset函数,而应该使用适当的C++等效函数。同时,不要手动管理动态数组的内存,应该使用std::vector代替。请注意保持原文意思不变。 - Konrad Rudolph
2
为什么不用memset呢?只要这是一种数组OP想要的。另一个更严重的问题是第二个参数是计数,意思是6*sizeof(*a) - Michael Krelin - hacker
1
@Michael 除了其他事情之外,它只适用于POD,因此范围非常有限。在C++中根本没有它的位置,它完全被std::fill取代。 - Konrad Rudolph
2
不管你是否喜欢它,memset仍然是允许的。而且对于一个老派黑客来说,偶尔看到memset是一种享受 ;-)话虽如此,我很高兴我们都表达了自己的观点。这样既不会消除memset也不会滥用它的影响 ;) - Michael Krelin - hacker
3
@KonradRudolph 我同意你的观点:memset太容易出错了,因为有更安全的替代方案(通常也更快)。它还有一个额外的缺点,就是它告诉读者作者并不真正了解C++。 - James Kanze
显示剩余13条评论

-1
嘿,我认为处理这种操作的最快方法是使用memset()来清零内存。
示例-
memset(&myPage.pageArray[0][0], 0, sizeof(myPage.pageArray));
类似的C++方法是使用std::fill。
char *begin = myPage.pageArray[0][0];
char *end = begin + sizeof(myPage.pageArray);
std::fill(begin, end, 0);

7
std::memset 不比 std::fill 更快。 - Konrad Rudolph
@KonradRudolph 的代码 std::fill(buf, buf + n, '\0'); 可以改写为 memset - user21959052
@AndrewPilikin 没错,这就是我的观点。 - Konrad Rudolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接