指针的范围?

时间:2010-06-02 00:05:27

标签: c++ visual-studio visual-studio-2008 visual-c++

好的,所以我确实发现了一些几乎相似的问题,但实际上他们对指针更加困惑。

C++ Pointer Objects vs. Non Pointer Objects

在上面的链接中,他们说如果你声明一个指针它实际上保存在堆上而不是堆栈上,无论它在何处被声明。这是真的 ??还是我误会了?我认为无论指针还是非指针,如果它是一个全局变量,它就和应用程序一样长。如果它是一个局部变量或在循环或函数中声明,它的生命只与其中的代码一样长。

7 个答案:

答案 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要彻底理解声明和定义,变量范围和指针之间的差异。