Easy safe memory allocator class/functions

This is a discussion on Easy safe memory allocator class/functions within the C++ Programming forums, part of the General Programming Boards category; Hi. As some of you may know I am attempting to get various debugging tools turned into headers for inclusion ...

  1. #1
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875

    Easy safe memory allocator class/functions

    Hi. As some of you may know I am attempting to get various debugging tools turned into headers for inclusion of a project. This time around I started making a smartptr that could:

    1. Allocate a new object of type T
    2. If that object is used to access memory outside of the ptr buffer it could throw an assertion.

    By way of example if:
    Code:
    // old way
    int numElements = 5;
    double *ptrDoubleArray  = new double[numElements];
    // accessed like
    ptrDoubleArray[4] = 5; // okay
    ptrDoubleArray[10] = 5; // is not OK
    
    // With smartptr
    SmartPtr ptrSmart = new double[numElements];
    ptrSmart[4] = 5; //still OK
    ptrSmart[20] = 5; //smart ptr knows it "owns" addresses ptrSmart to ptrSmart + 5
                                 // so with an overloaded [] operator, it will internally do
    if( newRequestedElement > ptr + 5)
    {   
          assert();
    }
    else
    {
          return ptr[newRequestedElement];
    }
    So that logic (roughly) will tell me if an attempt to access the ptr is outside of its range plus the usual stuff a smart ptr does. However what I want to do now is detect when:
    1. The pointer itself is damaged.
    2. The data underneath the pointer has been stepped on
    3. The pointer itself has been damaged.

    I have theories on how to do this but would like to know either if
    A. I am nuts for trying this...wait scratch that.
    B. There is something like this out there.

    My theory is to use basic memory protection techniques:
    When the smart pointer does the basic allocation, it allocates memory sizeof(class T) plus two blocks at the beginning and end of that block 2*sizeof(classT) and here is the trick: when I allocate the memory with the guard buffers as described above, I cope the value of the actual ptr into both ends of the memory window. Further when the class is used normally a hash of the original memory block. The at periodic times in the source you can call checkPtr(someSmartPtr) which will compare the guards at the front and end of the memory block with the value of the actual ptr. If one of the guards and the ptr match but not the other one, it will assert with a stacktrace saying "Beginning" (if that is the odd-man out) or "End" if the latter guard doesn't match "Has been overwritten in file XXX.cpp on line YYY".
    If that is OK, the actual memory window is rehashed and if the hash value doesn't match the previous check, it reports that memory has been stepped on. No idea how to tell who did it yet but this is a start. If the value of the ptr and the beginning and ending guards match AND the checksum is correct it will return a success value.

    Not as good as a memory tool but could be useful.

    So does something like this exist?

    TIA
    Jeff
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  2. #2
    Registered User
    Join Date
    Nov 2008
    Posts
    26
    Why not use a vector?

  3. #3
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Quote Originally Posted by salquestfl View Post
    Why not use a vector?
    In what way would a vector address any of those requirements? Boundary checking, data corruption checking, etc?
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,430
    Quote Originally Posted by jeffcobb
    In what way would a vector address any of those requirements? Boundary checking, data corruption checking, etc?
    A vector would address boundary checking if you stick to the use of at(), but not the others.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,205
    Quote Originally Posted by jeffcobb View Post
    I have theories on how to do this but would like to know either if
    A. I am nuts for trying this...wait scratch that.
    B. There is something like this out there.
    I'm aware of a couple of small home-grown libraries that tried to do this sort of thing, but the authors eventually gave up (I'll try to find them - if I succeed, I'll follow up with pointers). The basic problem is that code which does an invalid pointer operation can potentially tromp on anything. No matter what scheme you use to detect corruption, there is always a likelihood some false negatives (a case that passes your test, but tromps something) exist.

    The reason such operations are classified as "undefined behaviour" by the C and C++ standards is that it is extremely difficult, if not impossible, for a compiler to identify the full range of possible erroneous behaviours.

    I don't think you're nuts for wanting to do this, but I do think - if you proceed - you will suffer tremendous frustration. Every time you think you have covered the bases, it will be possible to find some erroneous code that sails through your tests.

    Unfortunately, the only way to offer robust assurances that some code does not perform invalid operations is the hard way: rigorous analysis to ensure that a design eliminates unwanted errors, rigorous review of code to ensure it doesn't violate some assumption of the design, etc. Assurance processes are facilitated by ensuring the design is as simple as possible (i.e. avoid unnecessary complexity) but, in the end, it comes down to hard work. It is no accident that safety-critical code averages a much higher cost per line of code than does the code in a typical MP3 player - it takes significant effort to give higher levels of assurance.

    Writing tools (or debugging headers, in your case) simply shifts the focus of effort because the tool itself must be subjected to rigorous assurance processes. Increase the general-purpose nature of the tool (which would be necessary if you seek to over a wide range of arbitrary invalid operations), and more effort is needed to offer assurance that the tool covers all bases in a reliable manner.

    That doesn't mean you shouldn't try.

    The worst case result of your effort is that you will learn a lot: you will certainly gain broader insights into the way invalid operations can manifest. Which will help your future work, as you will tend to design and code your software in a way that reduces likelihood of squirrelly errors. Hence, even if you fail, you'll become a better developer. If you succeed, you'll prove my scepticism wrong - which I won't complain about, as it'll mean you have made some valuable contribution or breakthrough in the state of the art for detecting errors in software.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Java vs C to make an OS
    By WOP in forum Tech Board
    Replies: 59
    Last Post: 05-27-2007, 03:56 AM
  2. Relate memory allocation in struct->variable
    By Niara in forum C Programming
    Replies: 4
    Last Post: 03-23-2007, 03:06 PM
  3. Copying memory, pointers and the like.
    By psychopath in forum C++ Programming
    Replies: 34
    Last Post: 12-12-2006, 12:37 PM
  4. Shared Memory - shmget questions
    By hendler in forum C Programming
    Replies: 1
    Last Post: 11-29-2005, 01:15 AM
  5. Memory allocation and deallocation
    By Micko in forum C++ Programming
    Replies: 3
    Last Post: 08-19-2005, 06:45 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21