繁体   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