When making bigger maintaining changes on a Drupal site (like upgrading it) it's a common practice to make a copy of the whole site and database to a subdirectory (usualy on some other site) where everything can be done and tested before copying the result back to overwrite the live site.

How annoying is it then to discover that all the images disappear on the copy of the site when it goes into a subdirectory?

Well you could go and change all the image source paths to include the subdirectory. You could also do the same change by some nasty SQL hack, or make some rewriting trick in the .htaccess file. But then you'll have to change it back again when copying back to the live site! O_o

If you, like me, think, this can't be right, it's Drupal, there must be a better way.
Well you are correct. I have the solution for you ^_^

I found that there is two things that can cause this problem (or both at once):

1) Root reference in the image source path.
Look in the html source in your node editor. Perhaps you have written something like
<img src="/files/images/myimage.jpg" />
Well this is all good and sound on the main site, but when copied to a subdirectory the reference to root is becomming a problem. So just remove the root reference. You don't need it. Drupal knows the root. Change the above into this:
<img src="files/images/myimage.jpg" />

2) Clean urls are enabled along with module Path, but the 'url alias' is not filled
Clean urls is working fine on the live site, even if the 'url alias'/'url path settings' on the current node is not filled. But the Clean urls rewriting engine have a problem with subdirectories when the above combination is present. You could do one of the following to solve this. Either just turn Clean urls off when on the copied site (admin/settings/clean-urls) and turn it back on when copying back to the live site, or fill out the current node field 'url alias'/'url path settings', or disable module Path if you are not using the feature anyway.