Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill 3D array with zeros?

I am trying to fill a 3d array with zeros to "reset" all elements in the array with std::fill.

With a 2d array it works fine to use std::fill function like this:

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

Trying to fill a 3d array with zeros with the std::fill function does not work and I get the error: 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 );

Does anybody know how to use std::fill function if its even possible with a 3d array?

like image 611
Frans Avatar asked Sep 06 '25 14:09

Frans


1 Answers

I get the error: segmentation fault(core dumped)

The sizeof(histogram3D) returns value equalent to 28 * 28 * 28 * sizeof(float) that is 87808. When you do histogram3D[0][0][0], you are accessing the single float array element in the 3D array. Therefore in this line

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

you have access out of bounds undefined behaviour since you are trying to access the element which is not there. The UB means anything could happen. In your case, you just got a segmentation fault.


Does anybody know how to use std::fill function if it's even possible with a 3d array?

Yes, Indeed it is possible because a 3d array is still allocated as a contiguous block of memory where it packs its elements.

It will be then

#include <algorithm> // std::fill

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

However, I would prefer std::fill_n, as it just required the starting iterator (i.e. a pointer to the first element) and the size of the array.

#include <algorithm> // std::fill_n

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

Now to generalize this for any 3d-array with any initializing value, we can provide a templated function as follows:

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

like image 98
JeJo Avatar answered Sep 08 '25 11:09

JeJo