1

In Qt, I have a 3-D int-array (say ID[x][y][z]) which I need to set back to 0 during computation.

Is there an efficient way to do it without using a loop?

I need the reinitialization because I am running a specific algorithm with a simple cost-function to get an estimation for the following more detailed computation, and I want to use the same data structure. Simply overwriting the array is not an option, because the algorithm reads and checks entries before writing them.

Anthony Geoghegan
  • 11,533
  • 5
  • 49
  • 56
derMax
  • 355
  • 4
  • 7
  • 17

3 Answers3

3

Sooner or later there's going to be a loop, but you can delegate it to another and more optimized function.

Also, if the "3D array" is really an array of arrays of arrays of some basic type (like int or char), then all the memory is contiguous so you can use a single function call to clear all of the memory in one single call.

Now which function to use; In C++ there are basically two functions you can use: The old C memset function, and the C++ std::fill function. Both should work fine, with proper casting and size, to set all of the data to a specific value.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Under the hood it will (almost) always be a loop. Don't worry, a loop without branches is quite efficient.

If you go for more readable, you can use a function like memset or std::fill which hides the loop.

Have a look at the answers to this question: What's the safe way to fill multidimensional array using std::fill?

Community
  • 1
  • 1
Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
0

The users @JoachimPileborg and @GeorgSchölly have already explained in their answers which functions can be used to reinitialize an array. However, I'd like to add some sample code and explain a difference between std::fill() and memset().

I assume that you want to (re)initialize your array with 0. In this case you can do it as shown in the following code:

#include <xutility>  // For std::fill().

int main(int argc, char* argv[])
{
    const int x = 2;
    const int y = 3;
    const int z = 5;
    const int arraySize = x * y * z;

    // Initialize array with 0.
    int ID[x][y][z] = {};

    // Use the array...

    // Either reinitialize array with 0 using std::fill()...
    std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 0);

    // ...or reinitialize array with 0 using memset().
    memset(&ID[0][0][0], 0, sizeof(ID));

    // Reuse the array...

    return 0;
}

However, if you want to initialize your array with another value (for example, 1), then you have to be aware of a crucial difference between std::fill() and memset(): The function std::fill() sets each element of your array to the specified value. The function memset(), in contrast, sets each byte your array to the specified value. This is why memset() takes the array size as number of bytes (sizeof(ID)).

If you initialize your array with 0, this difference doesn't cause a problem. But, if you want to initialize each element of your array with a non-zero value, then you have to use std::fill(), because memset() will yield the wrong result.

Let's assume you want to set all elements of your array to 1, then the following line of code will yield the expected result:

std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 1);

However, if you use memset() in the following way, then you get a different result:

memset(&ID[0][0][0], 1, sizeof(ID));

As explained above, this line of code sets every byte to 1. Therefore, each integer element of your array will be set to 16843009, because this equals the hexadecimal value 0x01010101.

honk
  • 9,137
  • 11
  • 75
  • 83