Malloc and Void Pointers

26,969

Solution 1

The reason it returns a void pointer is because it has no idea what you are allocating space for in the malloc call. All it knows is the amount of space you requested. It is up to you or your compiler to decide what will fill the memory. The void pointer's location is typically implemented as a linked list to maintain integrity and know what values of memory are free which is surprisingly kept track of in the free function.

Solution 2

This is the implementation of malloc, so it is allowed to do things that would not be legitimate in a regular program. Specifically, it is making use of the implementation-defined conversion from unsigned long to void *. Program initialization sets malloc_ptr to the numeric address of a large block of unallocated memory. Then, when you ask for an allocation, malloc makes a pointer out of the current value of malloc_ptr and increases malloc_ptr by the number of bytes you asked for. That way, the next time you call malloc it will return a new pointer.

This is about the simplest possible implementation of malloc. Most notably, it appears not to ever reuse freed memory.

Solution 3

Malloc is returning a pointer for a chunk of completely unstructured, flat memory. The (void *) pointer means that it has no idea what it's pointing to (no structure), merely that it points to some memory of size size.

Outside of your call to malloc, you can then tell your program that this pointer has some structure. I.e., if you have a structure some_struct you can say: struct some_struct *pStruct = (struct some_struct *) malloc(sizeof(struct some_struct)).

See how malloc only knows the size of what it is going to allocate, but does not actually know it's structure? Your call to malloc is passing in no information about the structure, merely the size of how much memory to allocate.

This is C's way of being generic: malloc returns you a certain amount of memory and it's your job to cast it to the structured memory you need.

Solution 4

 p = (void *)malloc_ptr;

malloc returns a void pointer, which indicates that it is a pointer to a region of unknown data type. The use of casting is only required in C++ due to the strong type system, whereas this is not the case in C. The lack of a specific pointer type returned from malloc is type-unsafe behaviour according to some programmers:

malloc allocates based on byte count but not on type.

 malloc_ptr += size;

C implicitly casts from and to void*, so the cast will be done automatically. In C++ only conversion to void* would be done implicitly, for the other direction an explicit cast is required.

Wiki explanation about type casting: malloc function returns an untyped pointer type void *, which the calling code must cast to the appropriate pointer type. Older C specifications required an explicit cast to do so, therefore the code

(struct foo *) malloc(sizeof(struct foo))

became the accepted practice.

However, this practice is discouraged in ANSI C as it can mask a failure to include the header file in which malloc is defined, resulting in downstream errors on machines where the int and pointer types are of different sizes, such as the now-ubiquitous x86_64 architecture. A conflict arises in code that is required to compile as C++, since the cast is necessary in that language.

Solution 5

As you see this both lines,

p = (void *)malloc_ptr;
malloc_ptr += size;

here you are having malloc_ptr of type unsigned long so we are type casting this variable to void type and then store it in p. and in similar manner second one is denoting malloc_ptr = malloc_ptr + size;

And this both codes are for developer's comfortness as p is of type void pointer so in application when you use malloc then you don't know which type of memory block have to be return by function so this function is always returns this generic void pointer so we are able to typecast again in our application as per requirement.

and same in second code if you are enter size in negative then what happens with this condition

if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
error("Out of memory");
Share:
26,969
morcillo
Author by

morcillo

Updated on December 17, 2020

Comments

  • morcillo
    morcillo over 3 years

    I'm studying this malloc function and I could use some help:

    static void *malloc(int size)
      {
            void *p;
    
            if (size < 0)
                     error("Malloc error");
            if (!malloc_ptr)
                     malloc_ptr = free_mem_ptr;
    
            malloc_ptr = (malloc_ptr + 3) & ~3;     /* Align */
    
            p = (void *)malloc_ptr;
            malloc_ptr += size;
    
            if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
                     error("Out of memory");
    
            malloc_count++;
            return p;
     }
    

    I know that the malloc func allocates memory space for any type, if there is enough memory, but the lines i don't understand are:

    p = (void *)malloc_ptr;
    malloc_ptr += size;
    

    How can it point to any data type like that? I just can't understand that void pointer or its location.

    NOTE: malloc_ptr is an unsigned long

  • morcillo
    morcillo over 11 years
    but how does it know how much space to allocate? how does it use the size value? I just don't see it. For example I have a struct with 8 ints 3 chars and 1 float, called mystruct, and in theory it should allocate memory space for that much, but I just can't understand how
  • squiguy
    squiguy over 11 years
    @morcillo In that case you would probably use the sizeof operator which would determine the correct size in bytes needed to properly allocate that struct you declared.
  • morcillo
    morcillo over 11 years
    I know the sizeof is for that, but what I don't understand is how does it do to allocate space in memory. malloc_ptr has the size of the type but how does p = (void *)malloc_ptr know to allocate 8 bytes, or 2 bytes, or 152 bytes? is the casting to the malloc function that makes it work? (my_struct *)malloc(sizeof(my_struct))??
  • squiguy
    squiguy over 11 years
    @morcillo In this case, the function simply assigns the pointer to what I am assuming is a struct as a memory address. It then extends the size by the int you passed as a parameter and thus "extends" the memory allocation by size bytes returning you the leading pointer to that amount of memory.
  • morcillo
    morcillo over 11 years
    Thank you very much. Now the concept is clearer in my head. I'll keep on studying. Already gave you a check for correct answer ... hope that's a good enough christmas present.
  • squiguy
    squiguy over 11 years
    @morcillo Glad I could help.