簡體   English   中英

寫入 function 在 Visual Studio c++ 中引發讀取訪問沖突異常

[英]a write function throwing the exception of read access violation in visual studio c++

我嘗試寫入一個文件,但由於“訪問沖突讀取位置 0x0000000F”而無法寫入它我能夠隔離問題這里是示例代碼:

void test_1() {
    std::fstream fio{ "xyz.dat",std::ios::in | std::ios::out | std::ios::binary | std::ios::app };
    if (!fio) {
        std::cerr << "sorry no file";
        return;
    }
    std::string s_test{ "xyz hii \n workf" };
    fio.write( ( char* )(s_test.length()), sizeof( size_t ) );  //the write causing issue
}

( char* )(s_test.length())將字符串的長度視為指針並將地址 15 傳遞給write 由於地址 15 沒有有效字符,這會觸發Undefined Behavior ,這種情況下的行為是程序崩潰。

當被迫使用如此廣泛的演員表來強制重新解釋一個類型時,這總是一個問題。 你可能搞砸了,所有編譯器的防御都被關閉了。 我對此沒有很好的解決方案。

您需要傳入一個合法地址,其中包含要進行write操作的長度。 為此,您需要創建一個可以獲取地址的變量。 &s_test.length(); 這里還不夠好,因為您不能獲取function返回的純右值的地址。

auto len = s_test.length();
fio.write( reinterpret_cast<const char*>(&len), sizeof( len ) );

請注意,編寫自動推導類型的變量或可以在編譯器實現之間更改的類型的變量是有風險的。 很難確定在另一端需要讀取多少字節。

uint32_t len = x.length();

會更安全,並且可能更緊湊,但存在長度超過 44 億個字符的字符串溢出的風險。 這是我願意承擔的風險。

另一個問題是endian 它不像以前那樣常見,但作者和讀者都需要就 integer 的字節順序達成一致。 htonlntohl可以通過保證字節順序來幫助減輕這種威脅。

假設您正在嘗試將字符串的長度寫入 output 文件,您可以這樣做:

size_t len = s_test.length();
fio.write( ( const char * ) &len, sizeof( size_t ) );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM