Uninitialized memory blocks in VC++

前端 未结 15 1238
鱼传尺愫
鱼传尺愫 2020-12-19 08:49

As everyone knows, the Visual C++ runtime marks uninitialized or just freed memory blocks with special non-zero markers. Is there any way to disable this behavior entirely w

相关标签:
15条回答
  • 2020-12-19 08:57

    If you build in Release mode instead of Debug mode, the runtime does not fill uninitialized memory at all, but it will still not be zeros. However, you should not depend on this behavior - you should either explicitly initialize the memory yourself with memset(), ZeroMemory(), or SecureZeroMemory(), or set a flag somewhere indicating that the memory is not yet initialized. Reading uninitialized memory will result in undefined behavior.

    0 讨论(0)
  • 2020-12-19 08:57

    You could create a memory manager also. Then you could override new and delete to pull from/put back a pre allocated chuck of memory.

    0 讨论(0)
  • 2020-12-19 08:58

    @Jeff Hubbard (comment):

    This actually inadvertently provides me with the solution I want: I can set pvData to NULL on _HOOK_FREE and not run into problems with 0xFEEEFEEE for my pointer address.

    If this is working for you, then it means that you are reading freed memory when you're testing for the NULL pointer (ie., the pointer itself resides in the memory you freed).

    This is a bug.

    The 'solution' you're using is simply hiding, not fixing, the bug. When that freed memory ever gets allocated to something else, suddenly you'll be using the wrong value as a pointer to the wrong thing.

    0 讨论(0)
  • 2020-12-19 08:59

    You say:

    I create and initialize a variable (via new), and that all goes just fine. When I free it (via delete), it sets the pointer to 0xFEEEFEEE instead of NULL. When I insert a proper check for NULL, as all good programs that manage their own memory should, I come up with problems as 0xFEEEFEEE passes a NULL check without problems.

    Even the debug heap routines of MSVC will not change the value of the pointer you're deleting - the value of the pointer you're deleting will not change (even to NULL). It sounds like you're accessing a pointer that belongs to the object you've just deleted, which is a bug, plain and simple.

    I'm pretty sure that what you're trying to do will simply cover up an invalid memory access. You should post a snippet of code to show us what is really happening.

    0 讨论(0)
  • 2020-12-19 09:03

    If it's working in release mode, it's because of shear luck.

    Mike B is right to assume that the debug fix is hiding a bug. In release mode, a pointer is being used that has been freed but not set to NULL, and the memory it points to is still "valid". At some point in the future, memory allocations will change, or the memory image will change, or something will cause the "valid" memory block to become "invalid". At that point, your release build will start failing. Switching to debug mode to find the problem will be useless, because the debug mode has been "fixed".

    I think we call all agree that the following code shouldn't work.

    char * p = new char[16];     // 16 bytes of random trash
    strcpy(p, "StackOverflow");  // 13 characters, a '\0' terminator, and two bytes of trash
    delete [] p;                 // return 16 bytes to the heap, but nothing else changes;
    
    if (p != NULL)               // Why would p be NULL?  It was never set to NULL
        ASSERT(p[0] == 'S');     // In debug, this will crash, because p = 0xfeeefeee and 
                                 // dereferencing it will cause an error.
                                 // Release mode may or may or may not work, depending on
                                 // other memory operations
    

    As just about every other poster has said, pointers should be set to NULL after calling delete. Whether you do it yourself or use boost or some other wrapper or even the macro in this thread is up to you.

    0 讨论(0)
  • 2020-12-19 09:07

    If you're reading uninitialized memory, your checks are most certainly not "valid". The memory is freed. It might already be in use for something else. You can't make any assumptions about the contents of uninitialized memory in C/C++.

    Java (and C#, I believe) will guaranteed that allocated memory is zeroed before use, and of course the garbage collection prevents you from seeing freed memory at all. But that isn't a property of the C heap, which exposes the memory directly.

    0 讨论(0)
提交回复
热议问题