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

1

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:

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
}
c++
visual-c++
c++17
asked on Stack Overflow Aug 7, 2020 by Amit kh • edited Aug 7, 2020 by Nicol Bolas

2 Answers

2

( char* )(s_test.length()) is treating the length of the string as though it's a pointer and passing address 15 into write. Since there is no valid character at address 15, this triggers Undefined Behaviour, and the behaviour in this case is the program crashes.

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. 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.

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. That's a risk I'm willing to put up with.

Another concern is 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. htonl and ntohl can help mitigate this threat by guaranteeing a byte order.

answered on Stack Overflow Aug 7, 2020 by user4581301 • edited Aug 8, 2020 by user4581301
1

Assuming that you are trying to write the length of the string to your output file, you can do it like this:

size_t len = s_test.length();
fio.write( ( const char * ) &len, sizeof( size_t ) );
answered on Stack Overflow Aug 7, 2020 by Paul Sanders • edited Aug 7, 2020 by Paul Sanders

User contributions licensed under CC BY-SA 3.0