web-dev-qa-db-ja.com

mallocを使用して新しいメモリを割り当てた後、memsetを呼び出す必要がありますか?

_#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int main(int argc, char* argv[])
{
    int *test = malloc(15 * sizeof(int));
    for(int i = 0;i < 15 ;i  ++ )
        printf("test is %i\n",test[i]);

    memset(test,0,sizeof(int) * 15);

    for(int i = 0 ; i < 15; i ++ )
        printf("test after memset is %i\n",test[i]);

    return 0;
}
_

私が得る出力は非常に奇妙です:

_    test is 1142126264
    test is 32526
    ...
    test is 1701409394
    test is 1869348978
    test is 1694498930
    test after memset is 0
    test after memset is 0
    test after memset is 0
    test after memset is 0
    test after memset is 0
    ...
    test after memset is 0
    test after memset is 0
    test after memset is 0
    test after memset is 0
    test after memset is 0
_

なぜそれが起こるのでしょうか?すぐに使える新しいメモリをmallocしただけだと思いましたか?

では、これはどうですか?

_int test[15];
_

memset(&test,0,sizeof(int) * 15);を呼び出す必要がありますか?

11
steave

mallocは、割り当てたメモリを初期化しません。あなたはただランダムなゴミがすでにそこにあったものを手に入れます。本当にすべてを0に設定する必要がある場合は、パフォーマンスを低下させてcallocを使用します。 (0以外に初期化する必要がある場合は、バイト配列にmemsetを使用するか、配列を手動でループして初期化します。)

20
1''

C11 7.22.3.4

void *malloc(size_t size);

Malloc関数は、sizeがサイズで指定され、値が不確定であるオブジェクトにスペースを割り当てます。

値をゼロに設定する場合は、代わりにcallocを使用してください。 callocは基本的に、mallocへの1回の呼び出しとmemsetへの1回の呼び出し(設定する値は0)のラッパー関数です。

2
Lundin

ヒープからメモリを要求すると、ヒープは使用可能なメモリのブロックを割り当てるだけです。このメモリブロックには、以前の書き込みによってはデータが含まれている場合があります。

1
Jay

パフォーマンス上の理由から、malloc()は新しく割り当てられたメモリの内容に関して保証しません。ゼロの場合もあれば、ランダムデータの場合もありますが、何でもかまいません。 mallocされたメモリに特定の値を持たせたい場合は、それを行うのはあなた次第です。

0
jdigital