2017-01-17 4 views
0

malloc()と文字列で、予期せぬ単純な結果が得られました。 コード:mallocがcharのメモリを割り当てていない*

int main(void) { 

char* b64str; 
char* binStr = "00000101"; 

printf("Expected size of allocated structure (b64str): 8\n"); 
b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char)); 
printf("Actual size of allocated structure (b64str): %d\n\n", strlen(b64str)); 

出力:

Expected size of allocated structure (b64str): 8 
Actual size of allocated structure (b64str): 0 

なぜ?

+1

から返されました。ドキュメンテーションと標準への言及とベスト。 – Olaf

+1

'b64str'は、新たに割り当てられたメモリを指します。あなたのシステムでは、その特定の実行で、メモリには最初にNUL文字が含まれています。何かを保存する前に実際にメモリにアクセスすべきではありません。Valgrindは、もしあなたがそれを使用するなら、このエラーを特定します。 –

答えて

4

b64strにスペースを割り当てましたが、そのスペースは初期化されていません。そのバッファ上でstrlenを呼び出そうとすると、undefined behaviorが呼び出されます。あなたの特定のケースでは、最初のバイトが0に設定されていましたが、その動作に依存することはできません。

どのくらいの量のメモリが割り当てられているかは分かりません。あなたはそれを自分で追跡する必要があります。

割り当てが失敗したかどうかを確認するには、返されたポインタがNULLであるかどうかを確認します。

b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char)); 
if (b64str == NULL) { 
    perror("malloc failed"); 
    exit(1); 
} 
0

strlen()は、文字列でNULターミネータを検索します。それはではありませんは、その文字列に割り当てられたバッファのサイズを教えてください! (最初のバイトが0の場合のみですが、他の実行では別の結果が生じる可能性があります)。

バッファのサイズは、必要に応じて自分で保存する必要があります。また、メモリが割り当てられているかどうかを確認する場合は、b64str自体がNULLであるかどうかを確認してください。

strlen()
2

ストリングなく、割り当てに関連するメモリの量のを報告します。

strlen関数は、終了ヌル文字に先行する文字数を返します。 3


C11dr§7.24.6.3はOPコードに変更を考えます。

char* binStr = "00000101"; 
printf("Result of strlen(binStr) %d\n", (int) strlen(binStr)); 
// Expect 8 to be printed. 

char* b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char)); 

strcpy(b64str, "123"); 
printf("Result of strlen(b64str) %d\n", (int) strlen(b64str)); 
// Expect 3 to be printed. 

strcpy(b64str, "12345"); 
printf("Result of strlen(b64str) %d\n", (int) strlen(b64str)); 
// Expect 5 to be printed. 

strcpy(b64str, "123");

size_t sz = strlen(binStr)+1)*sizeof(char); 
printf("Allocation size %d\n", (int) sz); 
// Expect 9 to be printed. 

後に標準的な方法はありません割り当てられたメモリの量がb64strによって指さこと9.注たこれら印刷割り当てサイズが9ままのなしmalloc()から返された非NULLポインターに関連付けられたメモリーの量を判別します。


malloc

コードが割り当てが成功したかどうかを知るためにmalloc()の戻り値をチェックしませんでしたchar*(OP)のためのメモリを割り当てません。 NULLのチェックを行います。コードが非NULLを受け取った場合、割り当てに成功しました。 NULLの戻り値は、サイズ要求が0の場合でもOKですが、strlen(binStr)+1では問題ありません。

malloc関数は、ヌルポインタまたは割り当てられた領域へのポインタを返します。 §7.22.3.42

char* b64str = malloc(strlen(binStr)+1); 
if (b64str == NULL) { 
    perror("OOM"); exit(-1); 
} 

注:

キャストmalloc()リターンを必要としません。
sizeof(char)タイプsize_tを一致させるために使用"%zu"

char* b64str = malloc(strlen(binStr)+1); 
if (b64str == NULL) { perror("OOM"); exit(-1); } 

常に1
堅牢なコードをチェック割り当て結果であるあなたは、その値を期待する理由を記入してくださいstrlen()

printf("Result of strlen() %zu\n", strlen(b64str));