1

私は以下のコードを持っています:

#include <stdio.h>
#include <unistd.h>

int main () {

    int fd = open("filename.dat", O_CREAT|O_WRONLY|O_TRUNC, 0600);
    int result = write(fd, "abcdefghijklmnopqrstuvxz", 100);
    printf("\n\nfd = %d, result = %d, errno = %d", fd, result, errno);
    close(fd);
    return 0;
}

使用可能なバイトよりも多くのバイトをファイルに書き込もうとするとどうなるかを理解しようとしています。だから私は呼び出しwriteて、プログラムに100バイトを書き込むように依頼していますが、それよりもはるかに少ないです。結果: からのたくさんのものは に行き着きstdoutますfilename.dat。代わりに100を使用するstrlen("abcdefghijklmnopqrstuvxz")と、目的の結果が得られます。'\0'私の質問は次のとおりです。プログラムが文字列の文字を超えて書き込もうとしているのはなぜですか? ここで未定義の動作が行われていますか?

4

5 に答える 5

4

私の質問は次のとおりです。プログラムが文字列の '\0' 文字を超えて書き込もうとしているのはなぜですか?

関数write(2)は 0 ターミネータを気にしません。実際には、バッファの内容はまったく気にしません。指定した数のバイトを書き込もうとします。

ここで未定義の動作が行われていますか

もちろん、あなたが持っている以上に書き込もうとすると、アクセスできないメモリに触れた場合にプロセスを終了することを決定する可能性のある OS の怒りを招く可能性があります。

于 2012-09-02T13:49:01.507 に答える
1

使用write()している関数は内容を気にしません。いいえと書いているだけです。ファイルに書き込むように指示するバイト数。

したがって、100バイトを書き込み、100バイト未満を提供するように言うと。残りのバイトはガベージ値として取得されます。

しかし、 を使用しているときは、文字列の長さに等しいバイトを書き込むstrlen("abcdefghijklmnopqrstuvxz")ように に要求しています。write()だからそれはそこでうまくいく

于 2012-09-02T13:52:53.823 に答える
1

文字列を表現するには 2 つの手法があるためです。null で終了するバージョンと、そのサイズと最初のバイトへのポインターを定義するバージョンがあります。書き込みは 2 番目のものを使用します。ファイルにコピーする必要があるデータの量を知るために、データの開始位置と長さを示すポインターが必要ですが、null 値は表示されません。これらのメソッドは単純な memcpy をラップすることがあります。

したがって、100 の長さを定義するとabcdefghijklmnopqrstuvxz、プログラムが「stdout の束」を格納した後のメモリに格納されます。だからゴミが見える。これらの場合、SEGFAULT を簡単に取得できるため、幸運でした。

于 2012-09-02T13:53:40.977 に答える
0

ここでの基本的な問題は、C 文字列を値として考えていること、この値を書き込み関数に渡していると考えていること、そして書き込み関数が値と余分ながらくたを書き出していることだと思います。

Cはそれより下のレベルです。C では、実際には文字列を渡すのではなく、文字列へのポインターを渡します。これは 'char *' 値ですが、null で終わる文字列として扱われるべき有効なメモリ ブロックを指すという約束が追加されています。 .

write() 関数は、null で終わる文字列規則を気にしません。書き込み呼び出しのパラメーターは、ファイル記述子、char *、およびバッファー長を提供します。

また、コンパイラは文字列定数を const char 配列に変換します。これと同等のことが最上位で発生します。

const char *stringconst00001[27] = { 'a', 'b', 'c', ... 'y', 'z', '\0' }

そしてそれは main() でこれを行います:

int result = write(fd, stringconst00001, 100);
于 2012-09-02T15:28:53.953 に答える
0

My question then is: why is the program trying to write beyond a \0100文字を書きたいからです。

Is there some undefined behavior going on here?その 100 を大きな数に増やし、その領域が非特権領域にある場合、それは未定義の動作です。

于 2012-09-02T13:52:07.370 に答える