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

C语言:为什么malloc()返回指针而不是值?,c,memory-management,malloc,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++) s

从我对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;
/'n'从用户处获取标准
...
int-someArray[n];
对于(int i=0;i
您不需要调用malloc()或其他函数就可以做到这一点吗?其他语言是否这样做(通过完全隐藏内存属性/位置)?我觉得作为一个初学者,处理你使用的变量的内存位置的整个过程只会让程序员感到困惑(而且因为其他语言不使用它,C似乎使一个简单的初始化过程变得过于复杂)

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

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

实际上C99允许这样做(所以你不是唯一想到它的人)。该特性称为VLA(可变长度阵列)

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

int n;
fscanf("%d", &n);
int array[n];
当然也有一些限制,因为
malloc
使用堆,
VLA
s使用堆栈(因此VLA不能像
malloc
ed对象那样大)

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


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

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

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

毕竟,指针允许您在创建对象的作用域之外保持对象的活动状态,您可以使用指向切片和骰子数组的指针(例如
strchr()
返回指向字符串的指针),指针是轻量级对象,因此将它们传递给函数并从函数返回它们非常便宜,等等


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

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

C允许您管理程序的每一点。当分配了内存时,您可以管理;当它被解除分配时,您可以管理;您可以管理如何增加少量分配,等等

如果您不想管理它,而让编译器为您执行,请使用另一种语言

基本上,我想问的是为什么malloc()是必要的, 因为为什么语言不能为你解决这些问题 在内部,程序员不必关心或 必须看到记忆

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


C语言已经有近40年的历史了,它还没有一些现代语言那么“高级”。有些语言,如Java,试图通过向程序员隐藏指针和显式内存管理来防止错误和简化编程。C不是那样的。为什么?因为事实并非如此。

对您的问题的简短回答是思考这个问题:如果您还需要精确控制何时取消分配内存,该怎么办?

基本上,我想问的是为什么malloc()是必要的,因为为什么语言不在内部为您处理所有这些,而程序员不必关心或查看内存。谢谢 C语言的一个特点是它的简单性(C编译器相对容易实现);使语言变得简单的一种方法是强迫程序员自己进行所有的内存管理。显然,其他语言确实为您管理堆上的对象——Java和C#是现代的例子,但这一概念一点也不新鲜;Lisp实现已经做了几十年了。但这种便利性是以编译器复杂性和运行时性能为代价的


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

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

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

malloc()