thematdev's blog

By thematdev, history, 3 days ago, translation,

Hello, Codeforces.

I've sent three submissions with different compilers on problem 1553E - Permutation Shift from last round and got different results(OK, ML 1, WA 1)

123344376

123363613

123363479

Then i've ran valgrind (g++ 11.1.0) and discovered strange "still reachable" memory addresses, somehow connected with ios_base::sync_with_stdio. Then I realised, that fast IO was in solve function, which is called in main $T$ times for each test case. Then I moved it to main and got OK in all compilers.

valgrind output on sample

Pretty strange and interesting situation, so I am asking those, who know what's the problem to write about it in comments. Also I am glad to see critics of my code, especially if it will help to avoid situations like this.

• +53

 » 2 days ago, # |   -38 It's normal,different compilers may have different Compiling environment
 » 2 days ago, # |   +28 The results are indeed very strange. However, the cppreference page for sync_with_stdio mentions the following: "If this function is called after I/O has occurred on the standard stream, the behavior is implementation-defined: implementations range from no effect to destroying the read buffer."In this case, the read buffer is probably destroyed in the GCC implementation (and somehow not in the MSVC one). As a result, the variables n and m don't get initialized properly from the call cin >> ..., and things go awry from there. Moreover, if you check the error flags in cin after unsyncing with stdio and then reading more input, you would find that cin.good() becomes false, whereas cin.eof() and cin.fail() become true. It means EOF is reached, so the buffered input from early is really gone. (See the reference page for basic_istream for more info.)This is an implementation-defined territory, and I guess it's not that far from undefined behavior (which is a main source for common bugs in programming), so it might be a good idea to try to avoid dealing with these territories.