2017-07-20 93 views
0

我在玩c11標準中提到的「新」stdio功能:open_memstreamfmemopen爲什麼setbuf與open_memstream文件崩潰?

編譯在Ubuntu 16.10用gcc或Rextester與鐺(見下面的鏈接),用於緩衝模式

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

調用函數setbuf與open_memstream拋出SIGSEGV創建的文件。 (我想設置無緩衝模式,而不是在每次寫入後調用fflush。順便說一下,fflush的工作原理。)

爲什麼setbuf(mf,NULL)崩潰?我做錯了什麼?

對其他函數返回的文件,fmemopen,setbuf(mf, NULL)的作品,似乎做了什麼樣的預期。

link to my example @rextester

+1

我不知道你從哪裏得到這個,但是這兩個函數肯定不是C11。他們是POSIX 2008,我認爲在其他系統上不支持。所以他們與C99和C11都沒什麼關係。我刪除這些標誌並添加POSIX。 –

+0

試圖改變完全在內存中工作的函數的緩衝行爲聽起來很奇怪。你不認爲你的實現提供者已經儘可能地優化了嗎?改變與設備相對應的文件的緩衝是有意義的,因爲這些緩慢(延遲或吞吐量),但是在這裏沒有。另外,無論如何,你只能在'fflush'後面訪問得到的緩衝區。 –

+0

謝謝Jens。實際上我預計這些內存映射流是無緩衝的,它們的後備內存立即包含最後一次寫入的結果。但事實並非如此。需要衝洗。這就是爲什麼我試圖設置無緩衝模式,並且似乎與其中一種模式一起工作的原因。 – ddbug

回答

1

嚴格地說,你試圖做什麼目前不支持POSIX。這也是沒有必要的,因爲open_memstream的規範基本上說沒有緩衝(至少我認爲這是意圖)。

看起來open_memstreamfmemopen都被添加到POSIX中,而沒有考慮與現有接口的交互。的setvbuf已經描述了從C標準複製和尚未更新並說:

setvbuf用來()之後的流指向由與打開的文件相關聯的函數可以被使用,但在任何其他操作之前[012]

這意味着對於新的流使用此函數將不被允許,因爲沒有關聯的文件。但我認爲這真的是一個意外,與open_memstreamfmemopen的互動完全沒有。在實現方面也發生了同樣的事情,因爲這個用例沒有被考慮,所以glibc在這裏崩潰。

同樣,fflush (NULL)是否應該對未被文件支持的流有影響尚不清楚。

+0

弗洛裏安。在我的例子中,我做了兩種類型的「內存文件」的FILE描述符,它可以工作(在調用fflush之前,後備內存爲空,在fflush包含預期內容之後)。但重點是我想避免。打電話給fflush。 – ddbug

+0

啊,有趣的用例。你是否想要確保傳遞給'open_memstream'的指針和大小值對於寫入緩衝區的內容始終是最新的? –

+0

如果可能的話。 – ddbug