C语言:为什么malloc()返回一个指针,而不是值?

时间:2011-10-13 18:54:35

标签: c memory-management malloc

根据我对C的理解,似乎你应该在尝试初始化时使用malloc(size),例如,在运行之前你不知道它的大小的数组。

但我想知道为什么函数malloc()会将指针返回到变量的位置以及为什么你需要它。

基本上,为什么C不会将它全部隐藏起来,所以无论何时你做这样的事情:

    // 'n' gets stdin'ed from the user
    ...
    int someArray[n];

    for(int i = 0; i < n; i++)
        someArray[i] = 5;

你可以在不必调用malloc()或其他函数的情况下完成它吗?其他语言是这样做的(通过完全隐藏内存属性/位置)吗?我觉得作为一个初学者,处理你使用的变量的内存位置的整个过程只会让程序员感到困惑(而且由于其他语言不使用它,C似乎做了一个简单的初始化过程,比如过于复杂)......

基本上,我想问的是为什么malloc()甚至是必要的,因为为什么语言不会在内部处理所有这些,而程序员不必担心或不得不看内存。感谢

*编辑:好的,也许有一些我不知道的C版本允许你放弃使用malloc()但是现在让我们试着忽略它......

9 个答案:

答案 0 :(得分:7)

C让您管理程序的每一点点。您可以管理 内存分配时;你可以管理 它被解除分配;您可以管理如何来增加小额分配等。

如果您不想管理它并让编译器为您执行此操作,请使用其他语言。

答案 1 :(得分:4)

实际上C99允许这样做(所以你不是唯一想到它的人)。该功能称为VLA(VAriable Length Array)。

阅读int然后拥有该大小的数组是合法的:

int n;
fscanf("%d", &n);
int array[n];

当然有限制,因为malloc使用堆而VLA使用堆栈(因此VLA不能像malloc ed对象那样大。)

  

*编辑:好的,也许有一些我不知道的C版本允许你放弃使用malloc()但是让我们试着忽略   现在......

所以我们可以专注于火焰?

答案 2 :(得分:4)

  

基本上,我想问的是为什么malloc()甚至是必要的,   因为为什么语言不会照顾你的一切   内部没有程序员必须关心或   不得不看到记忆。

malloc()的重点,它是存在的理由,它的功能,如果你愿意的话,就是分配一块内存。我们在C中引用一块内存的方式是它的起始地址,根据定义它是一个指针。

C接近40岁,并不像一些更现代的语言那样“高水平”。有些语言,比如Java,试图通过隐藏程序员的指针和显式内存管理来防止错误和简化编程。 C不是那样的。为什么?因为它不是。

答案 3 :(得分:3)

基本上,我想问的是为什么malloc()甚至是必要的,因为为什么语言不会在内部处理所有这些,而程序员不必担心或不得不看内存。感谢

C的一个标志是它的简单性(C编译器相对容易实现);使语言变得简单的一种方法是强迫程序员完成所有自己的内存管理。显然,其他语言为你管理堆上的对象 - Java和C#是现代的例子,但这个概念根本不是新的; Lisp实现已经做了几十年。但是,这种便利性会降低编译器复杂性和运行时性能。

Java / C#方法有助于消除C类特有的内存管理错误(内存泄漏,无效指针解引用等)。出于同样的原因,C提供了对内存管理的一定程度的控制,允许程序员实现高水平的性能,这在其他语言中很难(不是不可能)匹配。

答案 4 :(得分:2)

如果动态分配的唯一目的是分配可变长度数组,则可能不需要malloc()。 (但请注意,malloc()在将可变长度数组添加到语言之前很久了。)

但是在创建对象时,VLA的大小是固定的(在运行时)。它无法调整大小,只有当您离开声明它的范围时才会释放它。 (与malloc()不同,VLA没有报告分配失败的机制。)

malloc()为您提供很多更多的灵活性。

考虑创建链接列表。每个节点都是一个结构,包含一些数据和指向列表中下一个节点的指针。您可能事先知道每个节点的大小,但您不知道要分配多少个节点。例如,您可以从文本文件中读取行,为每行创建和附加新节点。

您还可以使用malloc()realloc()创建一个缓冲区(例如,unsigned char数组),其大小可以在创建后更改。

是的,有些语言不会公开指针,并且会为您处理内存管理。

其中很多是用C实现的。

答案 5 :(得分:1)

也许问题应该是“当你可以使用指针时,为什么需要像int array[n]这样的东西?”

毕竟,指针允许你保持一个对象活着超出它创建的范围,你可以使用指针切片和切块数组(例如strchr()返回一个指向字符串的指针),指针很轻-weight对象,因此将它们传递给函数并从函数等返回它们很便宜。

但真正的答案是“就是这样”。其他选项是可能的,并且证据是有其他语言做其他事情(甚至C99允许不同的事情)。

答案 6 :(得分:1)

C被视为高度发达的低级语言,基本上malloc用于动态数组,这是堆栈和组件中的关键组件。队列。对于隐藏开发人员指针部分的其他语言,它们不能很好地进行与硬件相关的编程。

答案 7 :(得分:1)

对你的问题的简短回答是思考这个问题:如果你还需要准确控制内存何时被解除分配,该怎么办?

答案 8 :(得分:0)

C是一种编译语言,而不是解释语言。如果您在编译时不知道n,编译器应该如何生成二进制文件?