Malloc and Void Pointers

℡╲_俬逩灬. 提交于 2019-12-30 04:45:10

问题


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


回答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.




回答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.




回答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.




回答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.




回答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");


来源:https://stackoverflow.com/questions/14033351/malloc-and-void-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!