2016-08-08 3 views
1
char *ptr = (char*)malloc(10); 

    if(NULL == ptr) 
    { 
     printf("\n Malloc failed \n"); 
     return -1; 
    } 
    else if(argc == 1) 
    { 
     printf("\n Usage \n"); 
    } 
    else 
    { 
     memset(ptr, 0, 10); 

     strncpy(ptr, argv[1], 9); 

     while(*ptr != 'z') 
     { 
      ptr++; 
     } 

     if(*ptr == 'z') 
     { 
      printf("\n String contains 'z'\n"); 
      /* Do some more processing */ 
     } 

     free(ptr); 
    } 

前のコードでは、プログラムの引数がMixxであるとします。ポインタをインクリメントするとポインタに割り当てられるメモリのサイズが変更されます

そして、私の質問は次のとおりです。
私はwhileループでこれを行うと:

ptr++; 

これはポインタptrに割り当てられたメモリの大きさも変化することを意味し、それは私が自由を呼んときですん()関数がクラッシュします。

+0

を私は悪い質問としてこれを表示されません。 (適切な説明とコードスニペット)。 UVを照射する。 – Bathsheba

+0

'while'ループ中に' \ 0'をチェックしないので、文字列の最後を読み取ってしまいます。 – Koshinae

+0

'argv [1]'に '' z ''が含まれていない限り、動作は '' free() '*の前であっても定義されていません。その結果、準拠しているコンパイラは '' if(* ptr == 'z') '-checkを取り除く可能性があります。 – EOF

答えて

4

あなたの勘違いは正しいです:あなたのプログラムの動作は未定義です。

あなたfreeptr値を渡す必要があります。

(また、while(*ptr != 'z')は、あなたの入力をオーバーランに対して脆弱である。あまりにも\0をチェックすることを検討してください。)

+0

あなたはwhileループで何回ptrがインクリメントされたのを数えてからそれを減らす必要があるということを意味していますか? –

+0

@ M.Cesar 'malloc'によって返されたポインタを' const'ポインタに受け入れ、後でそれをインクリメントするためのコピーを取ることは、もっと賢明ではないでしょうか? –

+0

これは一方的な方法ですが、元の値を別に保存しないのはなぜですか? – Bathsheba

1

あなただけfreemalloccalloc、またはreallocによって返されたポインタを渡すことができます。あなたが渡したものは、別のポインタでした。割り当てられたブロック内をポイントするということは問題ではありません。

元のポインタを解放して解放する必要があります。

char *ptr = (char*)malloc(10); 
char *ptr_sav = ptr; 

... 

free(ptr_sav); 

また、文字列をループすると、文字列の最後に達しているかどうかを確認していません。ヌルターミネータを過ぎて検索すると、所有していないメモリにアクセスし、未定義のビヘイビアを呼び出します。

次のようにチェックを追加します。

while(*ptr != 'z' && *ptr != '\0') 
+0

これは逆です。事故を避けるために、オリジナルを '* const'に受け入れ、ポインタ演算のために' _const'に_that_をコピーしてください。 –

関連する問題