2016-05-06 4 views
1

これは何に興味がありますか?私はmemsetをしない場合、ヒープ割り当てによって初期化されていない値が作成されました

char *assign_value = (char*)malloc(10 * sizeof(char)); 
if(strlen(assign_value) == 0) { 
    strcpy(assign_value, "A"); 
} else { 
    strcat(assign_value, "A"); 
} 

上記の例では、初期化されていない値がヒープ割り当てによって作成されたというエラーが発生します。しかし、私は事を行い、malloc()とif文の間にmemset()を挿入すると同じエラーが表示されません。私はいくつかのsugestionsを聞きたい、これは正しい方法ではない場合、何が正しいことですか?

char *assign_value = (char*)malloc(10 * sizeof(char)); 
memset(assign_value, 0, sizeof(assign_value)); 
if(strlen(assign_value) == 0) { 
    strcpy(assign_value, "A"); 
} else { 
    strcat(assign_value, "A"); 
} 

ありがとう!

+1

'malloc'は決して初期化しません。あなたが望むなら 'memset'の後に' calloc'を使うことができます。 – ameyCU

答えて

2

assign_valuemalloc(10)で返された場合、strlen(assign_value)を呼び出すと問題が発生します。手動memset(assign_value, 0, 10);で、配列のすべてのバイトを設定することができます

  • :ここ

    修正問題への3つの方法があります。あなたの呼び出しは、sizeof(assign_value)がポインタのサイズであり、配列のサイズではないと評価されているので、間違っていることに注意してください。

  • calloc(10, sizeof(char))で配列を割り当てることができます。callocは、すべてのビット0に初期化されたメモリブロックのアドレスを返します。これは、memsetを呼び出すのと同じ効果がありますが、潜在的により効率的です。

  • あなたはstrcpystrcatの両方で使用するために有効な、配列に空の文字列を作るために'\0'に最初のバイトを設定することができます。あなたが使用する前に割り当てられたデータの一部またはすべてを初期化に失敗した場合calloc()代わりのmalloc()を使用して

は、予期しない動作を避けるために良い習慣です。あなたのコードが根本的に簡素化することができ

注:strcat()を呼び出し先の文字列が実際に空の場合は、strcpy()に相当です。あなただけ書くことができます。

char *assign_value = calloc(10, sizeof(char)); 
... 
strcat(assign_value, "A"); 

をさらに、あなたはstrcat()が既にバッファに格納されている文字列の長さをチェックすることにより、バッファオーバーフローを引き起こさないことを確認する必要があります。

char *assign_value = calloc(10, sizeof(char)); 
... 
if (strlen(assign_value) < 10 - 1) { 
    strcat(assign_value, "A"); 
} else { 
    // handle the error: not enough space in assign_value 
} 
+0

答えてくれてありがとう、私は今日何か新しいことを学んだ。ニースアンサー –

1

はい、メモリはmallocから戻ってきますが、初期化されていません。一般に、予測不可能なランダムな値が含まれます。偶然にランダムな値になるかもしれませんが、これは全くカウントできません。

あなたが気にしている場合は、常にmallocから戻ってくるメモリを初期化する必要があります。 1つの方法はmemsetに電話することです - 投稿した例は珍しいですが。あなたはちょうど戻ったすべてのメモリをゼロにしたい場合は、通常の呼び出しは次のようになり

memset(assign_value, 0, 10); 

(その代わりmallocの、あなたもcallocを使用することができます。malloccallocの違いはcallocが自動的に初期化しないということになったら

assign_valueを文字列として使用していて、空の文字列として開始したい場合は、そのすべてをゼロにする必要はありません。それはちょうど最初の位置にnull文字を置くのに十分なのです。だからあなたのテストif(strlen(assign_value) == 0)は常に成功します0の長さで、あなたはこれらのもののいずれかを実行したら

*assign_value = '\0'; 

は、assign_valueは空の文字列を保持し、あなたの後のコードでは、いつもという決してstrcpyと呼ぶことになります。

最後に、を呼び出すときに、sizeof(char)を乗算するか、結果をキャストする必要はありません。だから、単純に使用することができますsizeof(char)は常に、定義により、正確に1であるので、(あなたがsizeof(char)で乗算する必要はありません

char *assign_value = malloc(10); 

明示的にCにmallocの結果をキャストする必要はありません、エラーを隠すことができます)

0

malloc()は、メモリを割り当てますがありませんそれを初期化しないでください。割り振られたメモリ位置に何が起こったとしても、あなたが得るものです。 mallocを使用した場合
は、だから、バッファ作成および初期化するのが最善である:ここでは、より多くの読書のために

char *assign_value = calloc (10,1);//note sizeof(char) is always 1 

:一方

char *assign_value; 
assign_value = malloc(10 * sizeof(char)); 
memset(assign_value, 0, 10); 

calloc()をメモリを割り当て、0に割り当てられたすべての位置を初期化しますディスカッションはcomparing malloc() and calloc()です。

[m] [c] allocの出力をC++でそのままCにキャストする必要はありません。

関連する問題