1

memsetを使用してints、shorts、floats などの組み込み型の配列を初期化するコードをいくつか書きました。

typedef void* slot_t;
#define EMPTY_SLOT (slot_t)NULL
...
int n = 10;
slot_t slots[] = (slot_t[])malloc(sizeof(slot_t)*n)
memset(slots,(int)EMPTY_SLOT,n*sizeof(slot_t));

このコードは、2 番目の引数 (つまり、初期化要素) としてmemset32 ビット s を受け入れるLinux32ではうまく機能しますが、 Linux64 ではそうではありません。私のプロジェクトで発生しているバグのいずれかがこれによるものであることをまだ確認していませんが、とにかく、より安全でありながら「一般的な」方法が存在する場合は、それを採用することをお勧めします。何でも知ってますか?intsizeof(slot_t)>sizeof(int)memsetchar

4

5 に答える 5

2

使用する

slot_t slots[] = (slot_t[])calloc(n,sizeof(slot_t))

それ自体がクリーンなメモリです

于 2011-08-05T23:46:37.060 に答える
1

memset実際には、メモリを埋める値として文字が必要です。バイトごとに埋められることに注意してください。だからただ言って0ください。EMPTY_SLOT必要に応じて、それをマクロに入れることができます。または、 を使用しますcalloc()

(また、malloc()呼び出しの戻り値の型は である必要がありますslot_t *。)

于 2011-08-05T23:44:19.957 に答える
1

memsetメモリをバイトで埋めます。ここを参照してください。

一般的な解決策が必要な場合は、反復して塗りつぶすループを作成する必要があります。0 で埋める場合は、データの種類やサイズは関係ありません。siezof配列全体 ( sizeof(slot_t)*n) を 0 で埋めてください。を使用してNULLいるため、これは 0 である必要はありません (ただし、通常は 0 です)。より安全な「ループ」アプローチを使用することをお勧めします。

于 2011-08-05T23:47:18.817 に答える
0

オブジェクトの配列を「テンプレート」オブジェクトで指定された値に設定する完全に汎用的な関数が必要な場合は、次のような関数を使用できます。

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 つの関数の最後のパラメーターの意味が微妙に異なるのが好きかどうかはわかりません。プログラムで両方の種類の初期化が必要な場合は、ポインター配列の初期化にも汎用的なものを使用することに固執するでしょう。少し効率が悪いかもしれませんが、通常、初期化はボトルネックにはなりません。

于 2011-08-06T23:59:05.630 に答える
0

の 2 番目の引数は int 型ですが、宛先の各バイトmemset()に格納される値を指定します。つまり、 の場合、本来あるべきメモリの 4 倍のメモリをゼロに設定していることになります。sizeof(int) == 4

slots配列をゼロで埋める方法は次のようになります

memset(slots, 0, n * sizeof *slots);

(slots配列ではなくポインターとして正しく宣言されていると仮定します)。

完全な移植性が必要な場合は、各要素を NULL に設定するループを記述する必要があります。

ヌル ポインターがすべてビット ゼロであると想定する場合は、memset-- を使用できますが、指定したとおりに呼び出すようにしてください。

于 2011-08-05T23:46:19.453 に答える