【问题标题】:How to fill 3D array with zeros?如何用零填充 3D 数组?
【发布时间】:2018-11-30 22:48:09
【问题描述】:

我正在尝试用零填充 3d 数组,以使用 std::fill“重置”数组中的所有元素。

对于二维数组,使用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 函数用零填充 3d 数组不起作用,我收到错误:分段错误(核心转储)

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 函数将其“重置”为零,但它不起作用。
  • 你的指针算法是错误的。第二个参数应该是&histogram3D[0][0][0] + sizeof(histogram3D) / sizeof(histogram3D[0][0][0])
  • @rpress 哦,当然谢谢。感谢您的帮助:)。

标签: c++ arrays algorithm c++11 multidimensional-array


【解决方案1】:

我收到错误:segmentation fault(core dumped)

sizeof(histogram3D) 返回的值等于28 * 28 * 28 * sizeof(float) that is 87808。 当您执行 histogram3D[0][0][0] 时,您正在访问 3D 数组中的单个 float 数组元素。因此在这一行

fill( &histogram3D[0][0][0], &histogram3D[0][0][0] + sizeof(histogram3D), 0 );

您可以越界访问undefined behaviour,因为您正在尝试访问不存在的元素。 UB 意味着任何事情都可能发生。在您的情况下,您只是遇到了分段错误。


有人知道如何使用std::fill 函数吗? 可以使用 3d 数组

是的,确实这是可能的,因为 3d 数组 仍被分配为一个连续的内存块,用于打包其元素。

以后会这样

#include <algorithm> // std::fill

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

但是,我更喜欢std::fill_n,因为它只需要起始迭代器(即指向第一个元素的指针)和数组的大小。

#include <algorithm> // std::fill_n

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

现在为了推广任何具有任何初始化值的 3d 数组,我们可以提供a templated function,如下所示:

#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)

【讨论】:

  • Bjarne Stroustrup 会接受这个答案。他在书中写道:不要使用原始数组,你会遇到问题。改用vector,它是为支持原始数组不能做或正在以危险方式做的许多事情而构建的。
  • 但这些并不是真正的 3D 数组,数据不会是连续的,也不适合缓存
  • @phuclv 是的,当然,这很糟糕。我只是想指出,关于拥有std::vector 的便利性。无论如何,我已经更新了数组方法。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-10-05
    • 2021-11-25
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2012-09-06
    • 1970-01-01
    • 2016-11-06
    相关资源
    最近更新 更多