如果我为char a[256]
分配内存,请将每个元素初始化为不同的值并将其传递给某个函数:
int subFunc(a);
subFunc
的堆栈帧看起来如何?
堆栈帧是否包含其中的所有256个字节,或者仅包含指向a
(4个字节)地址的指针。
如果是指针,那么它如何访问subFunc
内的数据或subFunc
可用的数据?
答案 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}的指针”类型的表达式}“,表达式的值将是数组第一个元素的地址。此规则的例外情况是数组表达式是T
,T
或一元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);