Thread: Valid, Initialized Allocated Memory

  1. #1
    Registered User
    Join Date
    Feb 2022
    Location
    Canada, PEI
    Posts
    103

    Valid, Initialized Allocated Memory

    What is a good way to ensure that allocated memory is initialized to a value? I know one can follow strict coding practices but I'm wondering how one can ensure allocated memory is properly initialized?

    I tried the code below:
    Code:
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    
    #define ARR_SIZE 5
    
    typedef bool SET;
    
    void check_allocation(void * ptr) {
      if (!ptr) {
        fputs("Allocation Failed!\n", stderr);
        exit(1);
      }
    }
    
    struct valid_memory {
      SET set;
      int * value; 
    };
    
    int main(int argc, char ** argv) {
      struct valid_memory vm[ARR_SIZE] = {
        {false, NULL}, 
        {false, NULL}, 
        {false, NULL}, 
        {false, NULL}, 
        {false, NULL}
        };
    
      for (size_t i = 0; i < ARR_SIZE; ++i) {
        if (vm[i].set) {
          fprintf(stdout, "set: %s, ptr: %p\n", vm[i].set ? "true" : "false", (void*)vm[i].value);
        }else {
          fprintf(stdout, "set: %s\n", vm[i].set ? "true" : "false");
        }
      }
      
      for (size_t i = 0; i < ARR_SIZE; ++i) {
        vm[i].value = malloc(sizeof(*vm[i].value));
        check_allocation(vm[i].value);
        *vm[i].value = i;
        vm[i].set = true;
      }
    
      for (size_t i = 0; i < ARR_SIZE; ++i) {
        if (vm[i].set) {
          fprintf(stdout, "set: %s, ptr: %p, value: %d\n", vm[i].set ? "true" : "false", (void*)vm[i].value, *vm[i].value);
        }else {
          fprintf(stdout, "set: %s\n", vm[i].set ? "true" : "false");
        }
      }
    
      for (size_t i = 0; i < ARR_SIZE; ++i) {
        free(vm[i].value);
        vm[i].value = NULL;
        vm[i].set = false;
      }
    
      for (size_t i = 0; i < ARR_SIZE; ++i) {
        if (vm[i].set) {
          fprintf(stdout, "--set: %s, ptr: %p, value: %d\n", vm[i].set ? "true" : "false", (void*)vm[i].value, *vm[i].value);
        }else {
          fprintf(stdout, "set: %s\n", vm[i].set ? "true" : "false");
        }
      }
    
      return 0;
    }
    Output from the above:

    set: false
    set: false
    set: false
    set: false
    set: false
    set: true, ptr: 0000000000BD13E0, value: 0
    set: true, ptr: 0000000000BD1400, value: 1
    set: true, ptr: 0000000000BD1420, value: 2
    set: true, ptr: 0000000000BD1440, value: 3
    set: true, ptr: 0000000000BD1460, value: 4
    set: false
    set: false
    set: false
    set: false
    set: false

    This problem seems simple at first but with some reflection it really exposes how dangerous C programming can get.

  2. #2
    Registered User
    Join Date
    Apr 2021
    Posts
    140
    I am unsure what you are asking, and the code does not clarify it for me.

    You appear to be concerned with the value of the pointer being null, which has nothing to do with allocated memory being initialized to a value, and everything to do with checking the return value of the memory allocator.

    I would suggest that you create a "personalized" library and use that in lieu of the C standard library functions. Develop this over time, but each library call should be replaced with a (for example) "g_" version that is your own implementation. Mostly, these will call the underlying stdlib function, but will include whatever error checking or handling you like:
    Code:
    static inline
    void *
    g_malloc_impl(
        size_t size,
        const char * file,
        int line)
    {
        void * result = malloc(size);
        if (is_null(result)) {
            // POLICY question:  What do you do on error?
            // This answer will likely change from desktop to embedded system...
    
            fatal_error(file, line, "malloc(%zu) failed", size);
        }
    
        return result;
    }
    
    #define g_malloc(size) (g_malloc_impl((size), __FILE__, __LINE__))
    Most of the time your fatal error policy will be the same. The default, for one-off apps on the desktop, is probably just fprintf-and-exit. If you're in a more "nuanced" environment, such as writing plugins for a web browser or text editor, then you probably have an infrastructure already defined. If you're in an embedded environment, you'll definitely have such a thing defined (or you wouldn't be asking this question, yet!)...

  3. #3
    Registered User
    Join Date
    Feb 2022
    Location
    Canada, PEI
    Posts
    103
    Quote Originally Posted by aghast View Post
    I am unsure what you are asking, and the code does not clarify it for me.
    I basically want to check if allocated memory has a proper(initialized) value. I want to check if the allocated memory was initialized.

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Quote Originally Posted by G4143 View Post
    I basically want to check if allocated memory has a proper(initialized) value. I want to check if the allocated memory was initialized.
    malloc() does not initialize the memory to any specific value. The contents are whatever was in the memory when allocated.

    calloc() will initialize the all the bytes allocated to nul bytes. (All bits set to zero)

    If you want memory assigned, not initialized, to some specific value(s), you can use memset() or manually assign values in the allocated memory.

    Please see the man pages for malloc(), and memset().

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Your question has nothing to do with dynamic allocation.
    You are asking about how to determine if a variable has a "valid" value or not.
    This is done differently depending on the situation.
    For example, if you have an array of ints whose valid values are all positive you can initialize them to 0 (or -1 if 0 is a valid value) to indicate an invalid value.
    If both positive and negative (and zero) values are valid you could use INT_MIN to indicate an invalid value.
    If valid values must also include INT_MIN then you would need to do something like you are doing where a separate boolean (or possibly a bit-array to save space) indicates if the value is valid. This is pretty rare.
    For different data types you could come up with similar schemes.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. checking memory/pointer if it's valid before deleting
    By stanlvw in forum C++ Programming
    Replies: 3
    Last Post: 04-23-2009, 08:06 PM
  2. Allocate memory inside allocated memory block?
    By Heidi_Nayak in forum C Programming
    Replies: 14
    Last Post: 04-15-2009, 04:19 PM
  3. validating memory - minimum address of valid location
    By m37h0d in forum C++ Programming
    Replies: 12
    Last Post: 09-05-2008, 10:50 PM
  4. Memory allocated
    By saswatdash83 in forum C Programming
    Replies: 2
    Last Post: 07-15-2008, 02:28 AM
  5. Memory not allocated??
    By Alexisa in forum C Programming
    Replies: 7
    Last Post: 09-24-2003, 11:19 PM

Tags for this Thread