2017-12-12 20 views
-1

私はmalloc()とさまざまな文字列関数とのやりとりをテストして、ポインタとメモリがC言語でどのように動作するかを学びましたが、以下のやり取りについて少し混乱します。mallocとstrcpyのやりとり

char *myString = malloc(5); // enough space for 5 characters (no '\0') 
strcpy(myString, "Hello"); // shouldn't work since there isn't enough heap memory 
printf(%s, %zd\n", myString, strlen(myString)); // also shouldn't work without '\0' 
free(myString); 

上記のすべてが正しく動作するように見えます。私はヌルターミネータが存在するかどうかを確認するためにprintf()を各文字に使用しようとしましたが、とにかに空白として印刷するには '\ 0'が表示されます。

私の混乱はである:

  • 文字列リテラルは、常に暗黙のヌルターミネータを持つことになります。
  • strcpyのはのmyStringにヌルターミネータをコピーする必要がありますが、十分に割り当てられたヒープメモリはありません
  • のmyStringはターミネータを持っていない限り、
  • のprintf/strlen関数が動作しないはず
  • のmyStringは明らかにヌルターミネータを持っているので

、 それはどこにある?それはちょうどランダムなメモリ位置に置かれましたか?上記のコードは発生するのを待っているエラーですか?

+4

バッファオーバーラン。 – jxh

+8

私の後で繰り返します: "未定義の動作"は "未定義"を意味します。それは、「失敗することを保証する」、「警告を生成する」、またはその他の予測可能なことを意味するものではありません。それがうまくいくからといって、それは何も間違っているというわけではありません。 –

+5

あなたのバッファオーバーランによって未定義の動作が呼び出されています。あなたは「すべての上記が適切に動作するように見える」ことだけが幸運になっています。本当に私は_un_luckyと言うべきです。なぜなら、このような問題が発生したときにあなたのプログラムがクラッシュして、修正することができるからです。そうでなければ、彼らは時代の中で最も無礼に現れます... – yano

答えて

3

あなたの三点アドレッシング:

  • 文字列リテラルは、常に暗黙のヌルターミネータを持つことになります。

修正。

  • strcpyのはのmyStringにヌルターミネータをコピーする必要がありますが、十分に割り当てられたヒープメモリがない

strcpyは、宛先バッファがどのように大きなを知る方法がない、と喜ん過ぎて書きます(バッファオーバーランやバッファオーバーフローの情報については、一般的なセキュリティ上の弱点です)。 より安全なバージョンを使用するには、宛先バッファの長さを引数として、末尾を超えて書き込まないように、strncpyを使用します。 myStringはターミネータ

prhase '働くべきではない' を持っていない限り、printfの/ strlen関数が動作しないはずです

  • ここで少し曖昧です。 printf/strlen/etcは、文字列の直後にあったり、何千バイトも離れていたりする可能性があるヌルターミネータが見つかるまでメモリからの読み取りを続けます(myStringの直後にヌルターミネータをメモリに書き込んだので、printf/strlen/etcはそこで停止します)。

    最後に: - 上記のコードは発生するのを待っていますか?

    はい。上書きされたことに応じて問題が発生する可能性がある、割り当てられていないメモリを上書きしています。 strcpy manページから :

    のstrcpyの先文字列は()、その後何かが起こるかもしれない、大きさが十分でない場合。オーバーフローしている固定長の文字列バッファは、マシンを完全に制御するのに最適なクラッカー技術です。プログラムがバッファにデータを読み込んだりコピーしたりするときには、プログラムはまず十分なスペースがあることを確認する必要があります。オーバーフローが不可能であることを示すことができますが、プログラムが時間の経過とともに不可能になる可能性がある方法で変更される可能性がある場合、これは不要です。

+0

'strncpy()'は指定された制限を超えて書き込みを行いませんが、コピーされたデータが必ずしも文字列である必要はないという欠点があります。最後にヌルバイトがないかもしれません。 –

関連する問題