1

I started out with Java, so I am a bit confused on what's going on with the stack/heap on the following line:

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

where x is a local variable. In C++, does ANYTHING happen on the stack at all in regards to that statement? I know from reading it says that the object is on the heap, but what about x? In Java, x would be on the stack just holding the memory address that points to the object, but I haven't found a clear source that says what's happening in C++.

trincot
  • 317,000
  • 35
  • 244
  • 286
id2341677
  • 319
  • 6
  • 13
  • 2
    Depends. Is `x` a local variable? – user703016 Jan 08 '12 at 22:43
  • Yes, it is local. I should have mentioned that. Will add it in, thank you. – id2341677 Jan 08 '12 at 22:47
  • Maybe [this answer of mine](http://stackoverflow.com/a/7462893/596781) is of some interest, or [this one](http://stackoverflow.com/a/7581238/596781), or [this one](http://stackoverflow.com/a/8439947/596781), or [this one](http://stackoverflow.com/a/6816851/596781), or [this one](http://stackoverflow.com/a/7620541/596781). – Kerrek SB Jan 08 '12 at 22:56
  • "...but I haven't found a clear source that says what's happening in C++" - The best source your going to get is the [C++ Standard](http://www.open-std.org/jtc1/sc22/wg21/), read "3.7 Storage Duration" and remember that local variables in C++ are usually called automatic variables as they have automatic storage duration. – Jesse Good Jan 08 '12 at 23:01

4 Answers4

3

Any object you just created, e.g. x in your example is on the stack. The object x is just a pointer, though, which points to a heap allocated string which you put on the heap using new string("Hello"). Typically, you wouldn't create a string like this in C++, however. Instead you would use

string x("Hello");

This would still allocate x on the stack. Whether the characters representing x's value also live on the stack or rather on the heap, depends on the string implementation. As a reasonable model you should assume that they are on the heap (some std::string implementation put short string into the stack object, avoiding any heap allocations and helping with locality).

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
2

yes, x is on the stack : it is a local variable, which are all on the stack.

The new operator provokes the allocation of memory on the heap.

rotoglup
  • 5,223
  • 25
  • 37
  • 1
    Ish. The C++ terms are "automatic" and "dynamic", which usually corresponds with the stack and heap respectively. – Mooing Duck Jan 08 '12 at 22:41
  • There's no such thing as "the new operator", and there are many things that can involve the word "new" in one way or another and do totally different things. – Kerrek SB Jan 08 '12 at 22:41
  • There's not enough code shown to know whether `x` is a local or not. – Ben Voigt Jan 08 '12 at 22:42
  • @KerrekSB: You seem to be off your game this time, even the standard uses the phrase "the `new` operator". – Ben Voigt Jan 08 '12 at 22:43
  • There is no such thing as "C++". – user703016 Jan 08 '12 at 22:45
  • @BenVoigt: Point is that *any* `new` *expression* creates a dynamic object with manually managed lifetime, but that says nothing about where the object is stored. And the last thing you want is for a novice to confuse `new` expressions with `operator new()` functions. (Yes, I know, the allocation function is called "operator", but now it's even more confusing :-).) – Kerrek SB Jan 08 '12 at 22:45
  • @KerrekSB: The `new` operator eventually uses an `operator new()` allocation function, but the two are not the same thing. A *new-expression* is application of the `new` or `new[]` operator. – Ben Voigt Jan 08 '12 at 22:47
  • @KerrekSB - Your phrasing will be very confusing to a Java programmer trying to learn C++. It would be better to say that, just like `+` (or pretty much any operator in C++), `new` can be overloaded to do totally different things. – Ted Hopp Jan 08 '12 at 22:48
  • @BenVoigt: OK, fair enough. In that case it is definitely incorrect that "the new operator *something something* heap". For example, `Foo x; x.~Foo(); ::new (&x) Foo;` is a perfectly legitimate `new` that doesn't go near any heap. – Kerrek SB Jan 08 '12 at 22:49
  • @KerrekSB: Ok, that I agree with. – Ben Voigt Jan 08 '12 at 22:50
  • @TedHopp: No, not quite. The *allocation functions* can be overloaded, but the semantics of *`new` expressions* are determined by the standard. – Kerrek SB Jan 08 '12 at 22:51
2

It's the same as in Java. The string or String is on the heap, and the pointer (or reference, in Java) is on the stack.

In Java, all the Objects are on the heap, and the stack is only made up of primitive types and the references themselves. (The stack has other stuff like return addresses and so on, but never mind that).

The main difference between the C++ stack and the Java stack is that, in C++, you can put the entire object directly onto the stack. e.g. string x = string("Hello");

It's also possible, in C++, to put primitive types directly onto the heap. e.g. int * x = new int();. (In other words, "if autoboxing is the solution, then what was the problem?")

In short, Java has rigid distinctions between primitive types and Objects, and the primitives are very much second-class. C++ is much more relaxed.

Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
  • 1
    No guarantee that the pointer is on the stack. They can also be embedded in other objects (not allowed by this particular syntax), locals with static duration, or globals. – Ben Voigt Jan 08 '12 at 22:46
  • All good points, @BenVoigt. But in this very particular example `string *x = new string("Hello");` isn't this guaranteed to be a local variable on the stack? (Except maybe for that new C++11 thing where I think that struct data members can be declared and defined like this.) – Aaron McDaid Jan 08 '12 at 22:59
  • It could have been a global (or namespace member), until the question was edited to say local. But I'm wanting to prevent the surprisingly common misunderstanding among Java and .NET programmers that "objects go on the heap, primitives and references go on the stack" which totally ignores members of other objects. – Ben Voigt Jan 08 '12 at 23:38
  • Yep. I daydreamed recently about how to draw diagrams to explain all that. Never mind teaching C++ to Java programmers, it's hard enough to explain Java to Java programmers :-) I might delete this answer, plenty of others will be able to do a better job. – Aaron McDaid Jan 08 '12 at 23:47
0

It depends on where this line is located. If it is located somewhere at file scope (i.e. outside of a function), then x is a global variable which definitely is not on the stack (well, in theory it could be put on the stack before calling main(), but I strongly doubt any compiler does that), but also not on the heap. If, however, the line is part of a function, then indeed x is on the stack.

Since x is of type string* (i.e. pointer to string), it indeed just contains the address of the string object allocated with new. Since that string object is allocated with new, it indeed lives on the heap.

Note however that, unlike in Java, there's no need that built-in types live on the stack and class objects live on the heap. The following is an example of a pointer living on the heap, pointing to an object living in the stack:

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
celtschk
  • 19,311
  • 3
  • 39
  • 64