Sometimes running a program under a debugger makes it work.   Running the same program without a debugger causes a failure or a crash.   Here are some reasons why this can happen:

1.   Timing - attaching a debugging changes timing and can hide race conditions.   Even without single-stepping and without using breakpoints, the debugger is affecting timing as it receives notifications from the operating system for every exception thrown,  creation of threads, loading dlls, etc.  

2.  Debug heaps – when running under a debugger, the operating system automatically enables heap validation.   This can help finding some types of heap corruption bugs, but sometimes have the opposite effect of hiding a race condition or use of already-free-memory on the heap.    This side effect can be avoided by using the –hd parameter (windows debugger) or by launching the process outside the debugger and attaching later.  You can get a similar effect on a process by using GFlags.  I’m not sure exactly which flags are enabled by the debugger, the following are likely candidates:  FLG_HEAP_ENABLE_FREE_CHECK, FLG_HEAP_VALIDATE_PARAMETERS, FLG_HEAP_ENABLE_TAIL_CHECK.   

3.  SeDebugPrivilege –  The debugger enables SeDebugPrivilege in its process token.   A debugger may need this privilege if it needs to open a process that belongs to a different user.  When a debugger creates a child process, that process inherits the privilege.   Usually, even if you run as administrator, this privilege is disabled by default and needs to be explicitly enabled for the process.   When your process is launched by the debugger it has access to some objects that it would otherwise fail to access.