Fastest way to zero out a 2d array in C? Fastest way to zero out a 2d array in C? c c

Fastest way to zero out a 2d array in C?


memset(array, 0, sizeof(array[0][0]) * m * n);

Where m and n are the width and height of the two-dimensional array (in your example, you have a square two-dimensional array, so m == n).


If array is truly an array, then you can "zero it out" with:

memset(array, 0, sizeof array);

But there are two points you should know:

  • this works only if array is really a "two-d array", i.e., was declared T array[M][N]; for some type T.
  • it works only in the scope where array was declared. If you pass it to a function, then the name array decays to a pointer, and sizeof will not give you the size of the array.

Let's do an experiment:

#include <stdio.h>void f(int (*arr)[5]){    printf("f:    sizeof arr:       %zu\n", sizeof arr);    printf("f:    sizeof arr[0]:    %zu\n", sizeof arr[0]);    printf("f:    sizeof arr[0][0]: %zu\n", sizeof arr[0][0]);}int main(void){    int arr[10][5];    printf("main: sizeof arr:       %zu\n", sizeof arr);    printf("main: sizeof arr[0]:    %zu\n", sizeof arr[0]);    printf("main: sizeof arr[0][0]: %zu\n\n", sizeof arr[0][0]);    f(arr);    return 0;}

On my machine, the above prints:

main: sizeof arr:       200main: sizeof arr[0]:    20main: sizeof arr[0][0]: 4f:    sizeof arr:       8f:    sizeof arr[0]:    20f:    sizeof arr[0][0]: 4

Even though arr is an array, it decays to a pointer to its first element when passed to f(), and therefore the sizes printed in f() are "wrong". Also, in f() the size of arr[0] is the size of the array arr[0], which is an "array [5] of int". It is not the size of an int *, because the "decaying" only happens at the first level, and that is why we need to declare f() as taking a pointer to an array of the correct size.

So, as I said, what you were doing originally will work only if the two conditions above are satisfied. If not, you will need to do what others have said:

memset(array, 0, m*n*sizeof array[0][0]);

Finally, memset() and the for loop you posted are not equivalent in the strict sense. There could be (and have been) compilers where "all bits zero" does not equal zero for certain types, such as pointers and floating-point values. I doubt that you need to worry about that though.


Well, the fastest way to do it is to not do it at all.

Sounds odd I know, here's some pseudocode:

int array [][];bool array_is_empty;void ClearArray (){   array_is_empty = true;}int ReadValue (int x, int y){   return array_is_empty ? 0 : array [x][y];}void SetValue (int x, int y, int value){   if (array_is_empty)   {      memset (array, 0, number of byte the array uses);      array_is_empty = false;   }   array [x][y] = value;}

Actually, it's still clearing the array, but only when something is being written to the array. This isn't a big advantage here. However, if the 2D array was implemented using, say, a quad tree (not a dynamic one mind), or a collection of rows of data, then you can localise the effect of the boolean flag, but you'd need more flags. In the quad tree just set the empty flag for the root node, in the array of rows just set the flag for each row.

Which leads to the question "why do you want to repeatedly zero a large 2d array"? What is the array used for? Is there a way to change the code so that the array doesn't need zeroing?

For example, if you had:

clear arrayfor each set of data  for each element in data set    array += element 

that is, use it for an accumulation buffer, then changing it like this would improve the performance no end:

 for set 0 and set 1   for each element in each set     array = element1 + element2 for remaining data sets   for each element in data set     array += element 

This doesn't require the array to be cleared but still works. And that will be far faster than clearing the array. Like I said, the fastest way is to not do it in the first place.