[英]a write function throwing the exception of read access violation in visual studio c++
I tried writing to a file and I am unable to write to it due to "Access violation reading location 0x0000000F" I am able to isolate the problem here is the sample code:我尝试写入一个文件,但由于“访问冲突读取位置 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())
is treating the length of the string as though it's a pointer and passing address 15 into write
. ( char* )(s_test.length())
将字符串的长度视为指针并将地址 15 传递给write
。 Since there is no valid character at address 15, this triggers Undefined Behaviour , and the behaviour in this case is the program crashes.由于地址 15 没有有效字符,这会触发Undefined Behavior ,这种情况下的行为是程序崩溃。
This is always a problem when forced to use such a wide cast to force re-interpretation of a type.当被迫使用如此广泛的演员表来强制重新解释一个类型时,这总是一个问题。 You can screw up horribly and all the compiler's defenses have been turned off.
你可能搞砸了,所有编译器的防御都被关闭了。 I don't have a good solution for this.
我对此没有很好的解决方案。
You need to pass in a legitimate address containing the length for write
to operate on.您需要传入一个合法地址,其中包含要进行
write
操作的长度。 To get this, you'll need to create a variable you can take the address of.为此,您需要创建一个可以获取地址的变量。
&s_test.length();
isn't good enough here because you cannot take the address of a prvalue returned by a function.这里还不够好,因为您不能获取function返回的纯右值的地址。
auto len = s_test.length();
fio.write( reinterpret_cast<const char*>(&len), sizeof( len ) );
Note that writing a variable of automatically deduced type or a variable of a type that can change between compiler implementations is risky.请注意,编写自动推导类型的变量或可以在编译器实现之间更改的类型的变量是有风险的。 It's hard to be sure how many bytes you're going to need to read at the other side.
很难确定在另一端需要读取多少字节。
uint32_t len = x.length();
Would be safer, and probably more compact, but at the risk of overflow with strings greater than 4.4 billion characters in length.会更安全,并且可能更紧凑,但存在长度超过 44 亿个字符的字符串溢出的风险。 That's a risk I'm willing to put up with.
这是我愿意承担的风险。
Another concern is endian .另一个问题是endian 。 It's not as common a problem as it used to be, but both the writer and reader need to agree on the byte order of the integer.
它不像以前那样常见,但作者和读者都需要就 integer 的字节顺序达成一致。
htonl
and ntohl
can help mitigate this threat by guaranteeing a byte order. htonl
和ntohl
可以通过保证字节顺序来帮助减轻这种威胁。
Assuming that you are trying to write the length of the string to your output file, you can do it like this:假设您正在尝试将字符串的长度写入 output 文件,您可以这样做:
size_t len = s_test.length();
fio.write( ( const char * ) &len, sizeof( size_t ) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.