Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I want to repeatedly zero a large 2d array in C. This is what I do at the moment:

// Array of size n * m, where n may not equal m for(j = 0; j < n; j++) {     for(i = 0; i < m; i++)     {           array[i][j] = 0;     } } 

I've tried using memset:

memset(array, 0, sizeof(array)) 

But this only works for 1D arrays. When I printf the contents of the 2D array, the first row is zeroes, but then I got a load of random large numbers and it crashes.

like image 828
Eddy Avatar asked Mar 25 '10 13:03

Eddy


People also ask

Can you pass a 2D array in C?

// The following program works only if your compiler is C99 compatible. If compiler is not C99 compatible, then we can use one of the following methods to pass a variable sized 2D array. In this method, we must typecast the 2D array when passing to function.

Does memset work on 2D array?

If the 2D array has automatic storage duration, then you can use an array initializer list to set all members to zero. int arr[10][20] = {0}; // easier way // this does the same memset(arr, 0, sizeof arr); If you allocate your array dynamically, then you can use memset to set all bytes to zero.


2 Answers

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

like image 99
James McNellis Avatar answered Oct 03 '22 03:10

James McNellis


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:       200 main: sizeof arr[0]:    20 main: sizeof arr[0][0]: 4  f:    sizeof arr:       8 f:    sizeof arr[0]:    20 f:    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.

like image 44
Alok Singhal Avatar answered Oct 03 '22 03:10

Alok Singhal