Указатели на объекты в C ++ - что находится в стеке / куче? - PullRequest
1 голос
/ 09 января 2012

Я начал с Java, поэтому меня немного смущает то, что происходит со стеком / кучей в следующей строке:

string *x = new string("Hello");

, где x - локальная переменная.В C ++ все ли происходит в стеке в отношении этого оператора?Я знаю, прочитав это говорит, что объект находится в куче, но как насчет x?В Java x будет находиться в стеке, просто храня адрес памяти, указывающий на объект, но я не нашел четкого источника, в котором говорится о том, что происходит в C ++.

Ответы [ 4 ]

3 голосов
/ 09 января 2012

Любой объект, который вы только что создали, например, x в вашем примере, находится в стеке.Однако объект x - это просто указатель, который указывает на выделенную кучу string, которую вы кладете в кучу с помощью new string("Hello").Как правило, вы не создадите такую ​​строку в C ++.Вместо этого вы бы использовали

string x("Hello");

Это все равно выделит x в стеке.Будь то символы, представляющие значение x, также в стеке или, скорее, в куче, зависит от реализации string.В качестве разумной модели вы должны предположить, что они находятся в куче (некоторые реализации std::string помещают короткую строку в объект стека, избегая выделения кучи и помогая с локальностью).

2 голосов
/ 09 января 2012

Это так же, как в Java. string или String находится в куче, а указатель (или ссылка в Java) находится в стеке.

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

Основное различие между стеком C ++ и стеком Java заключается в том, что в C ++ вы можете поместить весь объект непосредственно в стек. например string x = string("Hello");

В C ++ также возможно помещать примитивные типы непосредственно в кучу. например int * x = new int();. (Другими словами, «если автобокс является решением, то в чем проблема?»)

Короче говоря, у Java есть жесткие различия между примитивными типами и объектами, и примитивы очень похожи на второсортные. С ++ гораздо более расслаблен.

2 голосов
/ 09 января 2012

да, x в стеке: это локальная переменная, которая находится в стеке.

Оператор new вызывает выделение памяти в куче.

0 голосов
/ 09 января 2012

Зависит от того, где находится эта линия.Если он находится где-то в области видимости файла (то есть вне функции), то x - это глобальная переменная, которая определенно равна , а не в стеке (ну, теоретически она может быть помещена в стек раньшевызов main(), но я сильно сомневаюсь, что любой компилятор делает это), но тоже не в куче.Однако, если строка является частью функции, то действительно x находится в стеке.

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

Обратите внимание, однако, что в отличие от Java, нет необходимости в том, что встроенные типы живут в стеке, а объекты класса живут вкуча.Ниже приведен пример указателя, находящегося в куче, указывающего на объект, находящийся в стеке:

int main()
{
  std::string str("Hello"); // a string object on the stack
  std::string** ptr = new std::string*(&str); // a pointer to string living on the heap, pointing to str
  (**ptr) += " world"; // this adds "world" to the string on the stack
  delete ptr; // get rid of the pointer on the heap
  std::cout << str << std::endl; // prints "Hello world"
} // the compiler automatically destroys str here
...