There are two places to search for a differences between Debug and Release:
1) Compiler and linker flags. Compare them and read about every flag that has different values.
2) Conditional compilation. When _DEBUG constant is defined, some libraries and headers have different behavior. For example, C++ new operator is redefined as DEBUG_NEW operator, which keeps allocated object together with a file name and line number, where this allocation was done. Most assertions exist only in Debug configuration.

Regarding optimization. Non-optimized code is executed exactly as it is written. When you debug Debug configuration, executable code matches exactly the source code. Trying to debug Release configuration, you can see that many functions don't exist (inlined), many variables don't exist as well (replaced with constants, registers etc.), and generally, executable code does not match the source code.