如何用零填充3D数组?

4
我会尽力为您翻译。以下是您需要翻译的内容:

我正在尝试使用std :: fill将3D数组中的所有元素填充为零,以"重置"数组中的所有元素。

对于2D数组,可以像这样使用std :: fill函数:

float histogram2D[28][28] = {{0}};
//give the array some values here then trying to reset it with zeros.....
fill( &histogram2D[0][0], &histogram2D[0][0] + sizeof(histogram2D), 0 );

尝试使用 std::fill 函数用零填充一个三维数组不起作用,并且会出现错误:segmentation fault(core dumped)。
float histogram3D[28][28][28] = {{{0}}};
//give the array some values here then trying to reset it with zeros.....
fill( &histogram3D[0][0][0], &histogram3D[0][0][0] + sizeof(histogram3D), 0 );

有人知道如何使用std::fill函数来填充3D数组吗?


我所使用的C++版本不支持这样初始化数组。但这不是我的问题。当我给我的histogram3D赋值后,我想用std::fill函数将其“重置”为零,但它无法正常工作。 - Frans
你的指针算术有误。第二个参数应该是&histogram3D[0][0][0] + sizeof(histogram3D) / sizeof(histogram3D[0][0][0]) - rpress
@rpress 哦,当然谢谢。感谢你的帮助 :)。 - Frans
2个回答

6
我遇到了错误:segmentation fault(核心已转储)。 sizeof(histogram3D)返回的值等于28 * 28 * 28 * sizeof(float),即87808。当你使用histogram3D[0][0][0]时,你正在访问三维数组中的单个float数组元素。因此,在这一行中:
fill( &histogram3D[0][0][0], &histogram3D[0][0][0] + sizeof(histogram3D), 0 );

你访问的是不存在的元素,因此出现了越界未定义行为。UB 意味着任何事情都有可能发生。在你的情况下,只是出现了一个段错误。

有人知道如何使用std::fill函数填充一个三维数组吗?

确实可以,因为三维数组仍然会被分配为一块连续的内存,并将其元素打包。

然后就可以这样:

#include <algorithm> // std::fill

std::fill(
   &arr3D[0][0][0],
   &arr3D[0][0][0] + sizeof(arr3D) / sizeof(arr3D[0][0][0]),
   0.f);

然而,在IT技术中,我更喜欢使用std::fill_n,因为它只需要起始迭代器(即指向第一个元素的指针)和数组的大小。

#include <algorithm> // std::fill_n

std::fill_n(&arr3D[0][0][0], 28 * 28 * 28, 0.f);

现在,为了将其推广到任何带有任何初始化值的三维数组,我们可以提供一个如下的模板函数:函数模板
#include <algorithm> // std::fill_n, std::fill
#include <cstddef>   // std::size_t

template<typename Type, std::size_t M, std::size_t N, std::size_t O>
constexpr void fill_3D_array(Type(&arr3D)[M][N][O], const Type val = Type{}) noexcept
{
   std::fill_n(&arr3D[0][0][0], M * N * O, val);
   // or using std::fill
   // std::fill(&arr3D[0][0][0], &arr3D[0][0][0] + (M * N * O), val);
}

(See Live Demo Online)


2
Bjarne Stroustrup会接受这个答案。他在他的书中写道:不要使用原始数组,否则你将会遇到问题。相反,使用vector,它被设计来支持许多原始数组无法做到或者以危险的方式实现的功能。 - Volt
但是这些并不是真正的3D数组,数据不会是连续的,并且也不会是缓存友好的。 - phuclv
@phuclv 当然,这很糟糕。我只是想指出,拥有std::vector的便利性。无论如何,我已经更新了数组方法。 - JeJo

0

使用memset函数,语法为memset(histogram3D, 0, sizeof(histogram3D));


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