C语言 Malloc 和空指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14033351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:51:11  来源:igfitidea点击:

Malloc and Void Pointers

cmallocvoid-pointers

提问by morcillo

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

我正在研究这个 malloc 函数,我可以使用一些帮助:

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:

我知道 malloc func 为任何类型分配内存空间,如果有足够的内存,但我不明白的行是:

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

注意:malloc_ptr 是一个 unsigned long

采纳答案by squiguy

The reason it returns a void pointer is because it has no idea what you are allocating space for in the malloccall. 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 freefunction.

它返回空指针的原因是因为它不知道您在malloc调用中为什么分配空间。它只知道您请求的空间量。由您或您的编译器决定什么将填充内存。void 指针的位置通常被实现为一个链表,以保持完整性并知道哪些内存值是空闲的,这在free函数中令人惊讶地被跟踪。

回答by zwol

This is the implementationof 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 longto void *. Program initialization sets malloc_ptrto the numeric addressof a large block of unallocated memory. Then, when you ask for an allocation, mallocmakes a pointer out of the current value of malloc_ptrand increases malloc_ptrby the number of bytes you asked for. That way, the next time you call mallocit will return a new pointer.

这是实现malloc,所以它被允许做的事情,也不会在常规程序是合法的。具体来说,它正在利用实现定义的从unsigned long到 的转换void *。程序初始化设置malloc_ptr为一大块未分配内存的数字地址。然后,当您要求分配时,malloc从 的当前值中创建一个指针malloc_ptr并增加malloc_ptr您要求的字节数。这样,下次调用malloc它时将返回一个新指针。

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

这是关于malloc. 最值得注意的是,它似乎从未重用已释放的内存。

回答by Sunil Bojanapally

 p = (void *)malloc_ptr;

mallocreturns 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 mallocis type-unsafe behaviour according to some programmers:

malloc返回一个空指针,表示它是一个指向未知数据类型区域的指针。由于强类型系统,仅在 C++ 中需要使用强制转换,而在 C 中则不是这种情况。malloc根据一些程序员的说法,缺少从返回的特定指针类型是类型不安全的行为:

mallocallocates based on byte count but not on type.

malloc根据字节数而不是类型进行分配。

 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.

C 隐式转换 from 和 to void*,因此转换将自动完成。在 C++ 中,只有转换为void*隐式完成,对于另一个方向,需要显式转换。

Wikiexplanation about type casting: mallocfunction 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

关于类型转换的Wiki解释:malloc函数返回一个无类型的指针 type void *,调用代码必须将其转换为适当的指针类型。较旧的 C 规范需要显式转换才能这样做,因此代码

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

(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 mallocis 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.

然而,在 ANSI C 中不鼓励这种做法,因为它可以掩盖包含malloc定义的头文件的失败,导致 int 和指针类型大小不同的机器上的下游错误,例如现在无处不在的 x86_64 架构. 在需要编译为 C++ 的代码中会出现冲突,因为在该语言中强制转换是必需的。

回答by DWright

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.

Malloc 正在返回一个指向完全非结构化的扁平内存块的指针。(void *) 指针意味着它不知道它指向什么(没有结构),只是它指向某个大小为 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_structyou can say: struct some_struct *pStruct = (struct some_struct *) malloc(sizeof(struct some_struct)).

在调用 malloc 之外,您可以告诉程序该指针具有某种结构。也就是说,如果你有一个结构,some_struct你可以说: 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.

看看 malloc 如何只知道它要分配的大小,但实际上并不知道它的结构?您对 malloc 的调用不传递有关结构的信息,仅传递要分配的内存大小。

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.

这是 C 的通用方式:malloc 返回给你一定数量的内存,你的工作是将它转换为你需要的结构化内存。

回答by ravi bhuva

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;

在这里,您使用的是 unsigned long 类型的 malloc_ptr,因此我们将此变量类型转换为 void 类型,然后将其存储在 p 中。以类似的方式,第二个表示 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.

这两个代码都是为了开发人员的舒适度,因为 p 是 void 指针类型,所以在应用程序中,当您使用 malloc 时,您不知道函数必须返回哪种类型的内存块,因此该函数始终返回此通用 void 指针,因此我们可以根据要求在我们的应用程序中再次进行类型转换。

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