These two classes represent the main categories of errors in C++. runtime_error is for errors that can only be detected at runtime: file operations failing, network timeouts, invalid user input.
You can't prevent these through better code. logic_error is for programming errors: passing -1 when the function requires positive numbers, accessing index 10 of a 5-element array. Better code could prevent these.
The distinction helps during debugging. logic_errors suggest bugs to fix. runtime_errors suggest conditions to handle gracefully. Both should provide clear what() messages.