Checking if a pointer is allocated memory or not

前端 未结 18 1421
伪装坚强ぢ
伪装坚强ぢ 2020-11-28 07:30

Can we check whether a pointer passed to a function is allocated with memory or not in C?

I have wriiten my own function in C which accepts a character pointer -

18条回答
  •  感情败类
    2020-11-28 07:52

    I know this is an old question, but almost anything is possible in C. There are a few hackish solutions here already, but a valid way of determining if memory has been properly allocated is to use an oracle to take the place of malloc, calloc, realloc, and free. This is the same way testing frameworks (such as cmocka) can detect memory problems (seg faults, not freeing memory, etc.). You can maintain a list of memory addresses allocated as they are allocated and simply check this list when the user wants to use your function. I implemented something very similar for my own testing framework. Some example code:

    typedef struct memory_ref {
        void       *ptr;
        int        bytes;
        memory_ref *next;
    }
    
    memory_ref *HEAD = NULL;
    
    void *__wrap_malloc(size_t bytes) {
        if(HEAD == NULL) {
            HEAD = __real_malloc(sizeof(memory_ref));
        }
    
        void *tmpPtr = __real_malloc(bytes);
    
        memory_ref *previousRef = HEAD;
        memory_ref *currentRef = HEAD->next;
        while(current != NULL) {
            previousRef = currentRef;
            currentRef = currentRef->next;
        }
    
        memory_ref *newRef = (memory_ref *)__real_malloc(sizeof(memory_ref));
        *newRef = (memory_ref){
            .ptr   = tmpPtr,
            .bytes = bytes,
            .next  = NULL
        };
    
        previousRef->next = newRef;
    
        return tmpPtr;
    }
    

    You would have similar functions for calloc, realloc, and free, each wrapper prefixed with __wrap_. The real malloc is available through the use of __real_malloc (similar for the other functions you are wrapping). Whenever you want to check if memory is actually allocated, simply iterate over the linked memory_ref list and look for the memory address. If you find it and it's big enough, you know for certain the memory address won't crash your program; otherwise, return an error. In the header file your program uses, you would add these lines:

    extern void *__real_malloc  (size_t);
    extern void *__wrap_malloc  (size_t);
    extern void *__real_realloc (size_t);
    extern void *__wrap_realloc (size_t);
    // Declare all the other functions that will be wrapped...
    

    My needs were fairly simple so I implemented a very basic implementation, but you can imagine how this could be extended to have a better tracking system (e.g. create a struct that keeps track of the memory location in addition to the size). Then you simply compile the code with

    gcc src_files -o dest_file -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,free
    

    The disadvantage is the user has to compile their source code with the above directives; however, it's far from the worse I have seen. There is some overhead to allocating and freeing memory, but there is always some overhead when adding security.

提交回复
热议问题