2017-07-20 1 views
0

私はc11標準で言及されている "新しい" stdio関数で遊んでいます:open_memstreamfmemopen。 gccでまたは打ち鳴らすとRextester上のUbuntu 16.10でコンパイルなぜopenbufがopen_memstreamファイルでクラッシュするのですか?

がSIGSEGVをスローopen_memstreamで作成したファイルにバッファなしモードの

size_t sizeloc = 0; char *bufloc = NULL; 
FILE *mf = open_memstream (&bufloc, &sizeloc); 
setbuf(mf, NULL); // this crashes 

呼び出しはsetbuf(下記のリンクを参照してください)。 (私は毎回書き込み後にfflushを呼び出すのではなく、バッファされていないモードを設定したいと思っています)。

なぜsetbuf(mf、NULL)がクラッシュするのですか?私は間違っているの?

fmemopen,setbuf(mf, NULL)が動作し期待通りに動作しているようです。

link to my example @rextester

+1

これはどこから取得するのか分かりませんが、どちらの機能もC11ではありません。彼らはPOSIX 2008で、他のシステムではサポートされていないと私は思う。だから彼らはC99もC11もあまり関係ない。私はこれらのフラグを削除し、POSIXを追加します。 –

+0

メモリ内で完全に機能する関数のバッファリング動作を変更しようとすると、奇妙な音がします。実装のプロバイダが既に最適化しているとは思わないでしょうか?デバイスに対応するファイルのバッファリングを変更することは、遅い(遅延またはスループット)可能性があるため意味をなさないが、ここではこれは何もしない。さらに、 'fflush'の後で、結果バッファにアクセスすることもできます。 –

+0

ありがとう、ジェンス。実際に私は、これらのメモリマップされたストリームがバッファリングされておらず、バッキングメモリに直ちに書き込みが行われた結果が含まれることを期待していました。しかし、そうではありません。フラッシュが必要です。これがバッファリングされていないモードを設定しようとしていたため、これらのモードのいずれかで動作するようです。 – ddbug

答えて

1

厳密に言えば、何をやろうとしているが、現在、POSIXによってサポートされていません。 open_memstreamの仕様は基本的にはバッファリングがないと言っているので(少なくとも私はそれが意図だと思うので)、それは不要です。

既存のインターフェイスとのやり取りを考慮せずに、POSIXにopen_memstreamfmemopenの両方が追加されているように見えます。 setvbufの説明はC標準からコピーされ、更新されていませんと言う:

ストリームがストリームによって指さ後はsetvbuf()関数を使用することができるオープンファイルに関連付けられているものの他の操作の前に[...]

これは、関連付けられたファイルがないため、このストリームを新しいストリームに使用することはできません。しかし、これは実際には事故だと思うし、open_memstreamfmemopenとのやりとりは単に欠落していました。実装側でも同じことが起こりました。このユースケースも考慮されていないため、ここでglibcがクラッシュします。

同様に、fflush (NULL)がファイルバックアップされていないストリームに影響するかどうかは不明です。

+0

フロリアン。私の例では、両方の種類の "メモリファイル"のFILE記述子をfflushしています。fflushを呼び出す前に、バッキングメモリが空です。しかし、要点は避けたいのです。 fflushを呼び出す。 – ddbug

+0

ああ、面白い使用例。 'open_memstream'に渡したポインタとサイズの値がバッファに書き込まれたものに対して常に最新であることを確認しますか? –

+0

可能であれば、はい。 – ddbug

関連する問題