3

I'm trying to initialise an array to a non-zero value:

BYTE byteArray[50];
memset(byteArray, 20, sizeof(byteArray));   // Works fine

int intArray[50];
memset(intArray, 20, sizeof(intArray));     // Does not work

For now, am just manually initialising the array:

// Initialise array manually
for (int pos = 0; pos < 50; pos++)
    intArray[pos] = 20;

I do appreciate that memset sets every byte in the memory range, so this cannot work the way I need for multi-byte types (except for the special case where the requested value is 0). Is there a way to coerce memset for non-zero values using multi-byte types or perhaps there is an alternate library function?

AlainD
  • 5,413
  • 6
  • 45
  • 99
  • 3
    In C++ you can use [std::fill_n](http://en.cppreference.com/w/cpp/algorithm/fill_n) instead of memset. – Bo Persson Mar 03 '17 at 12:24
  • 1
    Any particular reason why you tagged this both C and C++? – Lundin Mar 03 '17 at 12:30
  • @Lundin: This is a C++ DLL (using Visual Studio). Nothing much object-oriented is done, so lots of C-style code. The suggested std::fill_n works perfectly. – AlainD Mar 03 '17 at 12:34
  • @BoPersson: Perfect, thanks! Just needed to `#include `. – AlainD Mar 03 '17 at 12:35
  • Besides the multi-byte `0` value you can also set the signed multi-byte value `-1` (if encoded as `0xFFFFFFFF`) or the unsigned `UINT_MAX` value, both of which may be useful for initialising an array. – Weather Vane Mar 03 '17 at 12:35
  • If the value is to be of repeating parts (eg for all values of an array of type uint16_t to be set to 0x2020), then yes, otherwise (e.g. 0x0020), then only for edge cases as Weather Vane mentions.. – Toby Mar 03 '17 at 12:42
  • In light of the comment above that this is for a C++ DLL, I've added the [C++] tag back in, especially as the poster has already said that `std::fill_n` is an acceptable solution. – JeremyP Mar 03 '17 at 14:29
  • @JeremyP: Yes that is right, `std::fill_n` works well. Perhaps whomever removed the [C++] tag did so because `memset` is a C-library function, but it was a bit overzealous since the question applies to the C/C++ family. Thanks. – AlainD Mar 03 '17 at 18:10
  • the `memset()` function works on bytes, it has no knowledge about any other object, like `int` – user3629249 Mar 05 '17 at 02:20

3 Answers3

6

Is there a way to coerce memset for non-zero values using multi-byte types

No.

or perhaps there is an equivalent C library function?

Not that I know of. Instead, you can use a simple loop.

But since you've tagged C++, there is an appropriate function in that standard library: std::fill or std::fill_n.

PS. memset doesn't only work with 0. It also works with all numbers with identically repeating byte pattern. Like for example ~0.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

In C you can initialize an array to one value like this:

#define ONE(n)   (n),
#define FIVE(n)  ONE(n) ONE(n) ONE(n) ONE(n) ONE(n)
#define TEN(n)   FIVE(n) FIVE(n)
#define FIFTY(n) TEN(n) TEN(n) TEN(n) TEN(n) TEN(n)

const int intArray [50] = { FIFTY(20) };

Or if you wish to assign it in run-time:

int intArray [50];
...
memcpy( intArray, &(int[50]){FIFTY(20)}, sizeof(intArray) );

A variable alternative that's easier to maintain:

#define I1(n)  (n),
#define I2(n)  I1(n) I1(n)
#define I3(n)  I1(n) I1(n) I1(n)
#define I5(n)  I1(n) I1(n) I1(n) I1(n) I1(n)
#define I10(n) I5(n) I5(n)
#define I50(n) I10(n) I10(n) I10(n) I10(n) I10(n)

#define INIT_FILL_ARRAY(n, val) I##n(val)

int main (void)
{
  const int intArray[] = 
  { 
    INIT_FILL_ARRAY(5, 20) 
    INIT_FILL_ARRAY(3, 10) 
    INIT_FILL_ARRAY(2, 123)
  };

  for(size_t i=0; i<sizeof intArray/sizeof *intArray; i++)
  {
    printf("%d %d\n", i, intArray[i]);
  }
}

Output:

0 20
1 20
2 20
3 20
4 20
5 10
6 10
7 10
8 123
9 123
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • @AlainD Not really, this is somewhat common practice. I posted a variable alternative. Now all you need to do is to add macros when you find them missing. – Lundin Mar 03 '17 at 13:08
-1

A very easy way to initialize an array :

int myArray[50] = {20};

which will initialize the whole array of int values to 20

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • 1
    This only sets the first element to 20...the rest are zeroes. This answer provides more details http://stackoverflow.com/questions/1065774/initialization-of-a-normal-array-with-one-default-value. `std::fill_n` does what I need. – AlainD Mar 06 '17 at 08:57