Because your program reads data from t1, reading data from t2, changing t2, and then writing the contents of t2.
When fp2 is opened first, the file looks like this ( ^ represents the current position of the file pointer):
 +-----------+-----------+-----------+-----------+ | t1 data | t2 data | t3 data | t4 data | +-----------+-----------+-----------+-----------+ ^ | 
After reading t1 and t2, the pointer will now point to the beginning of t3:
 +-----------+-----------+-----------+-----------+ | t1 data | t2 data | t3 data | t4 data | +-----------+-----------+-----------+-----------+ ^ | 
Now, to write t2 data, we need to move the file pointer back to the beginning of t2. How far is it? -1 * sizeof(t2) :
 +-----------+-----------+-----------+-----------+ | t1 data | t2 data | t3 data | t4 data | +-----------+-----------+-----------+-----------+ ^ | <-----------+ | This distance == sizeof(t2) 
From there, your program runs fp2.seekp(pos,ios::cur); . Since pos is negative, it moves the file pointer back, and your file remains in this state:
 +-----------+-----------+-----------+-----------+ | t1 data | t2 data | t3 data | t4 data | +-----------+-----------+-----------+-----------+ ^ | 
And now you can overwrite t2 data.
 source share