1

In C, How can I reset a given pointer to have all values in an array be a specified value? Is it best using a for loop, or is there a function that I can use to set all values in an array to 0.

My code currently is something like this:

int main()
{
     double *my_values = calloc(10, sizeof(double));
     do_something_with_values(my_values);

     free(my_values);
     my_values = calloc(10, sizeof(double));

     do_something_else_with_values(my_values);
     free(my_values);
}

This (to me) seems hacky, how can I improve this code?

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • Everyone recommends using memset to zero out memory. This works fine on all hardware where 0.0 is represented by all zero bits. Can't find where in the C standard that is required. ;-) – Bo Persson Mar 18 '11 at 17:39

8 Answers8

5

memset can set an array to all zero's or whatever value you want

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
4

The code is not just hacky, it could lead to severe and difficult to reproduce bugs.

By doing a free and then a new calloc call you are NOT guaranteed for the same memory space to be assigned to your array, this could be a problem if you have a pointer to this array before doing that and try to use it later.

Argote
  • 2,155
  • 1
  • 15
  • 20
  • 4
    +1 Even though this doesn't directly answer OPs problem, the question seems to indicate OP is mistaken about `calloc` mechanics, which makes it worth bumping this to the top. – corsiKa Mar 18 '11 at 17:04
1

If this is really always about fixed size arrays as in your example, you might be on the wrong track already with your allocation. Better do

int main(void) // <- this is the correct signature
{
     double my_values[10] = { 0 };
     do_something_with_values(my_values);

     memcpy(my_values, (const double[10]){0}, 10*sizeof(double));

     do_something_else_with_values(my_values);
}

The definition and initialization here ensures that the array is initialized with the correct value for 0.0 on whatever architecture you run this. The reinitialization with memcpy does the same. It uses a compound literal to achieve that. You'd have to have a C99 conforming compiler for that part.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

Once upon a time, it was 1975, someone started to write a library for a completely new programming language called C. If you had more than 64KB of RAM you had access to one of the world's largest supercomputers.

So when routines like memset() were designed, no one could imagine that you might want to initialize something bigger than an 8bit byte. A byte was huge at the time.

If you need something bigger, you must write your own loop. On the positive side, all C types are zero when all bytes are 0. So you can either use calloc() or get the memory from somewhere else and use memset(ptr, 0, size);

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 2
    Your last paragraph is true for most sane, real-world implementations but false as far as the standard is concerned. Only integer types are guaranteed to use all-bits-zero for their zero value. Pointer and floating-point types are allowed to use other representations of zero. – R.. GitHub STOP HELPING ICE Mar 18 '11 at 17:31
  • True but the IEEE standard (which is used by most CPUs today) says the same and also all wide-spread CPUs use the same (so you can quickly check a null pointer by loading it into a register and then branch on the ZERO flag). – Aaron Digulla Mar 20 '11 at 11:34
0

For initializations you can simple use:

double myarray[100] = {0};
user411313
  • 3,930
  • 19
  • 16
-1

The simplest way would probably be to use memset

    memset( the_array, '\0', sizeof(the_array) );

This will zero out your entire array

Mala
  • 14,178
  • 25
  • 88
  • 119
  • @Jesus: Mala's use of `sizeof` is correct. `memset` takes a number of bytes, not a number of array elements. – R.. GitHub STOP HELPING ICE Mar 24 '11 at 13:13
  • 1
    `memset` sets all BYTES to zero. Bitwise zero doesn't mean 0.0 float/double value. Yes, it will be 0.0 on most current platforms. But not on all. So code using `memset` or `calloc` for zeroing float/double array will be unportable. – Valeriy Van Jul 04 '19 at 16:39
-1

Use memset:

memset(my_values, 0, 10 * sizeof(double));
nmichaels
  • 49,466
  • 12
  • 107
  • 135
  • `memset` sets all BYTES to zero. Bitwise zero doesn't mean 0.0 float/double value. Yes, it will be 0.0 on most current platforms. But not on all. So code using `memset` or `calloc` for zeroing float/double array will be unportable. – Valeriy Van Jul 04 '19 at 16:38
  • C90 (Annex F) specifies that `double` matches the `IEC 60559` floating point format. That standard specifies a representation where if all 8 bytes are zero, the value is (positive) zero. If a platform interprets a double whose bits are all zero as something other than zero, it's not compliant with the standard. I don't have a copy of C99 or C11 handy, but I'd be shocked if they changed this. – nmichaels Nov 05 '19 at 22:04
-1

I may be completely off base here but: I would use memset.

http://www.linuxmanpages.com/man3/memset.3.php

Adam
  • 707
  • 1
  • 7
  • 15
  • `memset` sets all BYTES to zero. Bitwise zero doesn't mean 0.0 float/double value. Yes, it will be 0.0 on most current platforms. But not on all. So code using `memset` or `calloc` for zeroing float/double array will be unportable. – Valeriy Van Jul 04 '19 at 16:39