Dynamic linking is a form of linking where different programs share a single copy of a library in memory.
Linking in this case refers to the post-compilation process of copying object code from a library into an executable. After a source file is compiled, there are symbols in the object code which refer to external routines, such as printf. The link editor finds these symbols and places appropriate object code into the file. With static linking, the link editor copies the entire routine. By contrast, dynamic linking only places a stub which can access a shared library at runtime.
A shared library is loaded once into memory and made available for any program which wants its services. When a program requests that a dynamic library be loaded, the address of the library's routines are mapped into the program's virtual address space by the linker. When the program calls one of these routines, the address is translated to the actual location of the code, where it can run.
The advantage of dynamic linking is that significant space can be saved by compiling large libraries in shared fashion and loading them only once, allowing a large number of programs to use them, instead of loading a complete copy per process. The disadvantages are increased complexity in the linker and loader, as well as introducing the possibility of DLL hell, where a program written against one version of a library crashes when it tries to invoke functionality not available in a different version.