7

この質問に対する正確な答えが見つからなかったので、それはばかげた質問か、単なる明白な質問です。未定義の動作が発生するかどうかを知りたいです。

私はいくつかの構造体型を定義しています:

typedef struct {
    char string1[17];
    char string2[33];
    int   someInt;
    float someFloat;
} my_struct_t;

その構造体の複数のインスタンスが必要ですが (構造体配列にあるように)、オブジェクトの数はコンパイル時に不明です。

このように初期化するのは正しいですか?

my_struct_t *myStruct;
size_t noOfElements;
size_t completeSize;
int index;    

/* ...code which sets the number of elements at runtime... */

completeSize = sizeof(my_struct_t) * noOfElements;

myStruct = malloc(completeSize);
memset(myStruct, 0, completeSize);

/* ...and then access it as if it were an array...*/

myStruct[index].someInt = 10; // index < noOfElements

これを行うのは安全ですか?memset()気になるのはその部分です。

4

4 に答える 4

10

malloc後に続いて使用しmemsetても問題ありませんが、calloc代わりに (未使用) を検討することをお勧めします。例えば:

pMyStruct = calloc(noOfElements, sizeof(my_struct_t));

これにより、必要な数の要素にメモリが割り当てられ、バイナリ ゼロに初期化されます

于 2012-12-31T12:43:38.407 に答える
9

これを行うのは安全ですか?気になるのは memset() の部分。

はい、未定義の動作 (バッファ オーバーフロー、初期化されていない値など) が発生しないという意味で安全です。

ただし、必ずしも値がゼロに設定されるとは限りません。 ビットmemsetを 0 に設定しますが、これは、たとえば aを の値に設定することと必ずしも同じではありません(ただし、実際には、ほとんどの通常のプラットフォームでは問題ありません)。float0

于 2012-12-31T12:38:39.930 に答える
4

これを行うのは安全ですか?気になるのは memset() の部分。

あなたが心配するのは正しいです-あなたmemsetは単にすべてのビットをゼロに設定しますが、必ずしもメンバーを0に設定するとは限りません.

たとえば、all-bits-0 が float に対して実際に 0 を意味するという保証はありません。同じことがポインターにも当てはまります。すべてのビットを 0 にすることは、必ずしも になることを意味しませんNULL


編集

NULLすべてのビットが 0 として表される場合と表されない場合があります。C FAQ の引用:

null ポインターの内部 (または実行時) 表現。すべてのビットが 0 の場合とそうでない場合があり、ポインターの種類によって異なる場合があります。

于 2012-12-31T12:38:52.057 に答える
1

コード内のmemsetは、すべてのビットを0に設定します。これは、実行したいことである場合とそうでない場合があります。特に、すべてゼロビットのポインタがヌルポインタであるとは限りません。また、すべてゼロビットの浮動小数点値がゼロであることもありません。

コードを完全に移植可能にしたい場合は、各要素を初期化する必要があります。

my_struct_t *arr = malloc(N * sizeof arr[0]);
const my_struct_t default_my_struct = { 0 };
for (int i=0; i<N; i++)
    arr[i] = default_my_struct;

または、C99複合リテラルを使用して初期化を行うこともできます。

my_struct_t *arr = malloc(N * sizeof arr[0]);
for (int i=0; i<N; i++)
    arr[i] = (my_struct_t) { 0 };

実際には、上記のコードがを使用するバリアントとは異なる結果をもたらすC実装を見つけるために一生懸命努力する必要がありますmemset

于 2012-12-31T12:53:41.147 に答える