我查看了很多主题,但我仍然无法找到原因:
struct B
{
int _arr[5];
};
struct A
{
struct B * _pb;
};
int main() {
int i;
struct B b;
struct A *pa = (struct A*)malloc(sizeof (struct A));
for (i=0;i<5;++i)
{
b._arr[i] = i;
}
pa->_pb=&b;
Struct A a = *pb;
}
如何在堆栈上找到pa并在堆上找到* pa!两者都是局部变量,应该只在范围内有效,所以它应该在堆栈上。 还有为什么堆栈上的a._pb-&gt; _arr [2]不应该在堆上?任何人都应该在堆栈和堆上时为我澄清
答案 0 :(得分:2)
变量 pa
在堆栈中。它指向的内存在堆上。
有点图形化的指针变量可以这样描述:
+----+ +--------------------------------+ | pa | --> | allocated memory for structure | +----+ +--------------------------------+
上面说明的两个位置(pa
及其指向的记忆)可以位于不同的“段”中,也可以位于相同的位置。
a._pb->_arr[2]
位于堆栈上,因为a._pb
指向堆栈中的b
。
最后关于“堆叠”的说明。虽然将局部变量存储在堆栈中很常见,但C规范并未对其进行任何说明。局部变量实际上是automatic variables,而C规范只指定那些不应该存储它们的语义。
答案 1 :(得分:1)
首先,C标准对堆栈和堆没有任何说明。这些是给定编译器的实现细节。话虽这么说,桌面应用程序的大多数编译器都使用这两种编译器。
pa
是main
函数的本地,因此是正确的,因此它位于堆栈中。 *pa
但不是局部变量。它是一个表达式,其值为struct A
的实例。
在这种情况下,malloc
函数返回一个指针,指向一个足够大的struct A
内存块,该指针的值存储在pa
中。
一般来说,malloc
,realloc
或calloc
返回的任何内容都存在于堆中,而变量声明为函数的本地变量(甚至可能指向堆的指针变量)驻留在堆栈上。
答案 2 :(得分:0)
简短回答:在堆上找到* pa(pa指向的是什么),因为那是使用malloc()分配内存的地方。变量pa(指针本身)在堆栈上分配,因为它是一个局部变量。
答案很长:确保记下指针与指针所指的区别。
这样的声明:
int a [5]
告诉编译器为5元素数组保留空间,同时声明如下:
int * a;
告诉编译器为指针保留空间。如果你想让指针引用一个数组,你需要分配内存,通常在堆上使用malloc(),然后在你使用free()完成后释放它。
只是为了混淆事物,在C语言中,数组运算符[]相当于指针算术*(),因此这两个语句完全等价,无论a是被声明为指针还是阵列:
a [2] = 5;
*(a + 2)= 5;
题外话:这会带来一些有趣的可能性。以上两个陈述也与此相同:
2 [a] = 5;
因为加法在C中是可交换的:
2 [a] = 5;
*(2 + a)= 5;
*(a + 2)= 5;
a [2] = 5;
但是这绝对不适用于C ++,因为这个离题太远了。