область указателя? - PullRequest
3 голосов
/ 02 июня 2010

Хорошо, поэтому я нашел несколько вопросов, которые были почти схожи, но на самом деле они запутали меня еще больше в отношении указателей.

C ++ объекты-указатели и не-указатели

В ссылке выше они говорят, что если вы объявляете указатель, он фактически сохраняется в куче, а не в стеке, независимо от того, где он был объявлен. Это правда ?? Или я недоразумение ??? Я думал, что независимо от указателя или не указателя, если это глобальная переменная, он живет столько же, сколько приложение. Если это локальная переменная или она объявлена ​​в цикле или функции, срок ее службы равен длине кода внутри нее.

Ответы [ 7 ]

9 голосов
/ 02 июня 2010

Сама переменная хранится в стеке или сегменте DATA, но память, на которую она указывает после выделения с помощью new, находится в куче.

5 голосов
/ 02 июня 2010
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!

Надеюсь, это поможет.

3 голосов
/ 02 июня 2010
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), то это в куче. Вообще говоря, вы можете получить доступ только к динамически распределенной памяти, используя указатель. Вероятно, именно здесь возникает путаница.

3 голосов
/ 02 июня 2010

Необходимо различать указатель (переменная, которая содержит ячейку памяти) и объект, на который указывает указатель (объект по адресу памяти, удерживаемому указателем). Указатель может указывать на объекты в стеке или в куче. Если вы используете new для выделения объекта, он будет в куче. Указатель также может жить в куче. Если вы объявите его в теле функции, то это будет локальная переменная, которая будет находиться в локальном хранилище (то есть в стеке), тогда как если это глобальная переменная, она будет находиться где-то в разделе данных вашего приложения. Вы также можете иметь указатели на указатели, и аналогично можно выделить указатель на кучу (и указатель на указатель на это указывает) и т. Д. Обратите внимание, что хотя я ссылался на кучу и стек, только C ++ упоминает о локальном / автоматическом хранении и динамическом хранении ... это не говорит о реализации. Однако на практике local = stack и dynamic = heap.

1 голос
/ 02 июня 2010

Указатель - это переменная, содержащая адрес какого-либо другого объекта в памяти. Переменная указателя может быть выделена:

  • в стеке (как локальная auto переменная в блоке функции или оператора)
  • статически (как глобальная переменная или статический член класса)
  • в куче (как объект new или как член объекта класса)

Объект, на который указывает указатель (ссылки), также может быть размещен и в этих трех местах. Вообще говоря, объект, на который указывают, выделяется с помощью оператора new.

Локальные переменные выходят из области видимости, когда поток программы покидает блок (или функцию), в котором они объявлены, т.е. их присутствие в стеке исчезает. Аналогично, переменные-члены объекта исчезают, когда их родительский объект выходит из области видимости или удаляется из кучи.

Если указатель выходит из области видимости или его родительский объект удаляется, объект, на который указывает указатель, все еще существует в памяти. Таким образом, практическое правило: любой код, который выделяет (news) объект , владеет объектом и должен также delete этот объект, когда он больше не нужен.

Авто-указатели убирают часть рутинной работы с управления указанным объектом. Объект, который был выделен через auto_ptr, удаляется, когда этот указатель выходит из области видимости. Объект может быть присвоен от его владельца auto_ptr другому auto_ptr, который передает владение объектом второму указателю.

Ссылки по сути являются замаскированными указателями, но это тема для другого обсуждения.

0 голосов
/ 02 июня 2010

Похоже, вам нужно взять классическую книгу по K & R C и прочитать главы 4 и 5 для полного понимания различий между объявлением и определением, областью действия переменной и указателями.

0 голосов
/ 02 июня 2010

Я думал, что независимо от указателя или не указателя, если это глобальная переменная, он живет столько же, сколько приложение.Если это локальная переменная или она объявлена ​​в цикле или функции, срок ее службы составляет столько же, сколько в ее коде.

Это так.вы объявляете указатель, он фактически сохраняется в куче, а не в стеке

Это неправильно, частично.Вы можете иметь указатель на кучу или стек.Вопрос в том, где и как вы это объявляете.

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
}

... и компилятор может решить использовать регистр для указателя!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...