在C中堆栈帧

时间:2012-09-25 10:15:53

标签: c

如果我为char a[256]分配内存,请将每个元素初始化为不同的值并将其传递给某个函数:

int subFunc(a);

subFunc的堆栈帧看起来如何?

堆栈帧是否包含其中的所有256个字节,或者仅包含指向a(4个字节)地址的指针。

如果是指针,那么它如何访问subFunc内的数据或subFunc可用的数据?

4 个答案:

答案 0 :(得分:5)

C语言不需要基于堆栈的计算机。也就是说,在基于堆栈的机器上,可能会在堆栈上分配块作用域数组。

您无法将数组传递给C中的函数。该语言指定subFunc(a)接收指向a的第一个元素的指针。事实上,两个声明(或原型)subFunc (char *a)subFunc (char a[])被视为相同。

答案 1 :(得分:1)

subFunc会收到指向char的指针,而不是char的数组。传递指针的细节将随实现而变化。指针值可以被压入堆栈,或者它可以在寄存器中传递(Red Hat上的gcc 2.96执行前者,而SLES 10上的gcc 4.1.2执行后者),这可能取决于优化设置之类的事情无论您是否正在生成调试版本等。确定它在您的平台上的工作原理的唯一方法是对其进行编码,构建它,并查看生成的机器代码。

在大多数情况下,类型为“{-1}}的N元素数组”的表达式将被转换(“衰减”)为“指向{{1}的指针”类型的表达式}“,表达式的值将是数组第一个元素的地址。此规则的例外情况是数组表达式是TT或一元sizeof运算符的操作数,或者是用于初始化另一个数组内容的字符串文字在声明中。

给出代码

_Alignof

&调用中的表达式char a[256]; ... subFunc(a); 的类型为“{-1}}的256个元素数组”;根据上述规则,它将替换为“指向a”(subFunc)类型的表达式,其值为char的地址。

因此,char接收指针值,而不是char *的数组。

请注意,在函数参数声明的上下文中,a[0]subFunc被解释为char;如果T a[]的原型是

T a[N]

它将被解释为

T *a

答案 2 :(得分:0)

堆栈帧中只有一个4字节长的值(在32位操作系统上),其值是char a[256]的起始地址。现在我们知道了a的起点,我们可以访问数据。

答案 3 :(得分:0)

致电subFunc()的函数有char a[256]。并且该函数将首先在堆栈中。然后,subFunc()已被推入堆栈。但是,调用subFunc()的函数需要将a的第一个地址传递给subFunc()。如果您将a的长度传递给subFunc(),那会更好。 subFunc()应该像这样更改:

int subFunc(char *, int);