函数中的malloc变量会发生什么变化?

函数中的malloc变量会发生什么变化?,c,C,假设我使用malloc在函数中创建了一个变量: int f() { int* i=(int*)malloc(sizeof(int)); /* ... */ } 变量i位于何处?在堆或函数f()stack?i中是一个局部变量,因此编译器可以为其分配堆栈存储,但这取决于场景,在一些简单的用例中,编译器/优化器也可能避免堆栈而只使用寄存器 这个变量i,包含一个对应于整数大小空间的动态分配地址的数值。我将使用p而不是i,因为名为i的变量通常是整数 void function(void) {

假设我使用
malloc
在函数中创建了一个变量:

int f() 
{
 int* i=(int*)malloc(sizeof(int));
 /* ... */
}

变量
i
位于何处?在堆或函数
f()
stack?

i
中是一个局部变量,因此编译器可以为其分配堆栈存储,但这取决于场景,在一些简单的用例中,编译器/优化器也可能避免堆栈而只使用寄存器


这个变量
i
,包含一个对应于整数大小空间的动态分配地址的数值。

我将使用
p
而不是
i
,因为名为
i
的变量通常是整数

void function(void) {
    int *p = malloc(sizeof(*p));
}
这里有两件事:
p
*p
具有以下关系:

stack heap │ ... │ │ ... │ ┢━━━━━━━┪ ┢━━━━━━━┪ ┃ p ┃ ──→ ┃ *p ┃ ┡━━━━━━━┩ ┡━━━━━━━┩ │ ... │ │ ... │ 堆 │ ... │ │ ... │ ┢━━━━━━━┪ ┢━━━━━━━┪ ┃ P┃ ──→ ┃ *P┃ ┡━━━━━━━┩ ┡━━━━━━━┩ │ ... │ │ ... │ 从函数返回后,
p
将消失。但是,
*p
将保持分配状态,直到您调用
free()
。忘记调用
free()


注意:
p
不一定在堆栈上,但您可以假装它在堆栈上。它可以在寄存器中,也可以完全优化。它甚至可以在堆栈上移动。不管怎样,“堆栈”和“堆”的整个概念在技术上都是特定于实现的。

对于大多数系统,@Dietrich Epp的答案涵盖了这个问题。为完整起见,我想补充:

没有通用的方法来说明变量存储在哪里/如何存储。这不是标准的一部分。这取决于你的具体系统

c
中没有堆栈和堆这样的东西。这些概念是特定于系统的实现细节

标准(ISO/IEC 9899)规定了如下“存储持续时间”:

6.2.4对象的存储持续时间决定其生存期。有三个储藏室 持续时间:静态、自动和已分配

标准描述了相关的规则,但标准并不关心它是如何实现的


对大多数实现来说,
stack
heap
的使用是常见的,但这在任何方面都不是必需的。

变量是*i。它在那里,我们没有马洛克。这是一个指针

malloc返回堆中已分配内存的起始地址。并且=将此地址分配给指针


假设i=NULL,则将0分配给该指针,或者也可以将任何内容分配给它(例如4711)。但是,如果您通过读取或写入地址指向的内存来访问它,而它不在您的地址区域中,则会出现分段错误。

您不会使用
malloc
创建变量。你用它分配内存。你不是用
malloc
在函数中“创建变量”。变量
i
malloc
-ed内存之间没有任何关系,除了
i
最初恰好指向该内存之外。在C中,堆内存分配函数返回的类型是
void*
,可以分配给任何其他指针,强制转换返回的类型没有效果,只会使代码变得混乱,并且在维护代码时会出现问题。也就是说,不要强制转换返回值。问题询问“where is
I
?”并且说C标准没有回答问题也没有回答问题。(另外,C11中引入了第四个存储持续时间,其实现可以追溯到该标准发布之前很久。)@DietrichEpp我认为是这样,因为这是唯一正确的答案——如果不明确提及所使用的实现,您就不知道了。然而,说它在堆栈或其他任何地方都是错误的。就像假装
c
有堆栈和堆是错误的一样,堆栈溢出对于没有经验的开发人员来说可能是一种不友好的体验。以严格的技术正确回答问题是这种敌意的一个主要因素。考虑ASKER可能想从答案中学到什么信息,以及你的问题是否使AsKER更接近这一知识,或者它是否显示了你对C标准的知识。我坚持你要提到你引用的C标准的版本。@DietrichEpp——给出一个错误的答案——只是出于礼貌——我不应该这样做。我不认为告诉OP在OPs问题上有一个基本的误解是敌意的。这里OP显然认为堆和堆栈是
c
的一部分。你真的认为我们应该让OP继续那个误会吗?