好的,所以我确实发现了一些几乎相似的问题,但实际上他们对指针更加困惑。
C++ Pointer Objects vs. Non Pointer Objects
在上面的链接中,他们说如果你声明一个指针它实际上保存在堆上而不是堆栈上,无论它在何处被声明。这是真的 ??还是我误会了?我认为无论指针还是非指针,如果它是一个全局变量,它就和应用程序一样长。如果它是一个局部变量或在循环或函数中声明,它的生命只与其中的代码一样长。
答案 0 :(得分:9)
变量本身存储在堆栈或DATA段中,但在分配new
后指向的内存位于堆内。
答案 1 :(得分:5)
void main()
{
int* p; // p is stored on stack
p = new int[20]; // 20 ints are stored on heap
}
// p no longer exists, but the 20 ints DO EXSIST!
希望有所帮助。
答案 2 :(得分:3)
必须区分指针(保存内存位置的变量)和指针指向的对象(指针所占用的内存地址处的对象)。指针可以指向堆栈上或堆上的对象。如果使用 new 分配对象,它将在堆上。同样,指针可以存在于堆上。如果在函数体中声明它,那么它将是一个局部变量并存在于本地存储中(即在堆栈中),而如果它是一个全局变量,它将存在于应用程序数据部分的某个位置。你也可以有指针指针,同样可以在堆上分配一个指针(并指向一个指向指针的指针),等等。注意,虽然我引用了堆和堆栈,但只有C ++提到本地/自动存储和动态存储...它没有说明实现。但实际上,local = stack和dynamic = heap。
答案 3 :(得分:3)
void func()
{
int x = 1;
int *p = &x;
}
// p goes out of scope, so does the memory it points to
void func()
{
int *p = new int;
}
// p goes out of scope, the memory it points to DOES NOT
void func()
{
int x = 1;
int **pp = new int*;
*pp = &x;
}
// pp goes out of scope, the pointer it points to does not, the memory it points to does
等等。指针是包含内存位置的变量。与所有变量一样,它可以在堆或堆栈上,具体取决于它的声明方式。它的值 - 内存位置 - 也可以存在于堆或堆栈上。
通常情况下,如果您静态分配某些内容,则它位于堆栈中。如果你动态分配一些东西(使用new或malloc)那么它就在堆上。一般来说,您只能使用指针访问动态分配的内存。这可能是出现混乱的地方。
答案 4 :(得分:1)
指针是一个变量,包含内存中某个其他对象的地址。可以分配指针变量:
auto
变量)new
对象或类对象成员)指针指向的对象(引用)同样也可以在这三个位置分配。但是,一般来说,使用new
运算符分配指向对象。
当程序流离开块(或函数)时,局部变量超出范围,即它们在堆栈中的存在消失。类似地,当父对象超出范围或从堆中删除时,对象的成员变量将消失。
如果指针超出范围或删除其父对象,则指针引用的对象仍存在于内存中。因此,经验法则是任何分配(news
)对象的代码都拥有该对象,并且当该对象不再需要时也应该delete
该对象。
自动指针将一些苦差事从管理指向对象中解放出来。当指针超出范围时,将删除通过auto_ptr
分配的对象。该对象可以从其拥有的auto_ptr
分配给另一个auto_ptr
,它将对象所有权转移到第二个指针。
引用本质上是伪装的指针,但这是另一个讨论的主题。
答案 5 :(得分:0)
我认为无论指针如何 或非指针,如果它是全局的 变量,它只要活着 应用。如果是局部变量 或在循环或函数内声明, 它的生命只有代码 在其中。
这是真的。
他们说如果你宣布一个指针 它实际上是保存在堆上的 不在堆栈上
这是错误的,部分原因。您可以在堆或堆栈上有一个指针。这是你在何处以及如何宣布它的问题。
void main()
{
char c = 0x25;
char *p_stack = &c; // pointer on stack
StructWithPointer struct_stack; // stack
StructWithPointer *struct_heap = new StructWithPointer(); // heap, thus its pointer member "p" (see next line) is also on the heap.
struct_heap->p = &c; // pointer on heap points to a stack
}
......并且,编译器可能决定使用寄存器作为指针!
答案 6 :(得分:0)
看起来你需要抓住the classic K&R C book并阅读第4章和第4章。 5要彻底理解声明和定义,变量范围和指针之间的差异。