オブジェクトの配列を「テンプレート」オブジェクトで指定された値に設定する完全に汎用的な関数が必要な場合は、次のような関数を使用できます。
void init_array( void* arr, size_t nmemb, size_t size, void const* initializer)
{
size_t i = 0;
char* p = (char *) arr;
for (i = 0; i < nmemb; ++i) {
memcpy( p, initializer, size);
p += size;
}
}
次に、割り当て/初期化コードは次のようになります。
typedef void* slot_t;
static const slot_t empty_slot = NULL; // or make this a global if that
// works better for your scenario
int n = 10;
// note: your original `malloc()` line:
//
// slot_t slots[] = (slot_t[])malloc(sizeof(slot_t)*n)
//
// wouldn't work, as you can't assign to an array as a whole.
// That line shouldn't even compile.
slot_t* slots = (slot_t*)malloc(sizeof(slot_t)*n);
// completely generic initialization
init_array( slots, n, sizeof(slot_t), &empty_slot);
ポインターの配列を初期化する場合は、そのケースをもう少し直接的に処理する別の関数を使用できます。
void init_ptr_array( void* arr, size_t nmemb, void* initializer)
{
size_t i = 0;
void* p;
for (; p < arr + nmemb; ++p) {
*p = initializer;
}
}
// arrays of object pointers
init_ptr_array( slots, n, empty_slot);
2 つの関数の最後のパラメーターの意味が微妙に異なるのが好きかどうかはわかりません。プログラムで両方の種類の初期化が必要な場合は、ポインター配列の初期化にも汎用的なものを使用することに固執するでしょう。少し効率が悪いかもしれませんが、通常、初期化はボトルネックにはなりません。