Ahmed
Ahmed

Reputation: 15039

is this object on stack or heap?

In C++/CLI, are the following 2 same or different?

System::String ^source("Hello World");

System::String ^source= gcnew System::String("Hello World");

Is the first one on stack and second one on heap?
Or are they both on heap?
.Net objects I believe only have references they can't be created on stack unlike C++ allows us. Can someone explain please?

Upvotes: 1

Views: 153

Answers (1)

Hans Passant
Hans Passant

Reputation: 941635

The string is neither stored on the stack or the heap. The story is a bit convoluted.

The usually helpful way to think about it is that reference type objects are always stored on the GC heap. Pretty similar to C++ (aka std::string), variable length objects like strings need to use the free store to allocate the correct amount of memory. Modulo a possible micro-optimization in std::string that could store very short strings inside the std::string object. But normally the std::string object itself can be allocated on the stack and the string content is allocated on the heap. Just like source is on the stack, just a plain pointer that the garbage collector can find back.

The C language permits storing string content on the stack, but you have to guess the required string buffer length up front. Launching thousands of malware attacks, string buffer overflows are a standard technique to mess with the program's stack frame and alter the function return value. Not the .NET way. A C language compiler doesn't have to do it that way, they just very commonly do.

But it is not straight-forward in the example you gave. There is no difference between the statements, the string content is neither allocated on the stack nor the heap. The CLR is heavily micro-optimized to take advantage of the CLI spec, the standard that describes how strings must behave in a conformant CLR implementation.

It takes advantage of the property that string objects are immutable. That permits an optimization called interning. The string object looks and behaves like it is stored on the GC heap. But it actually isn't, the object content is directly read from the memory-mapped image of the assembly. Stored in the "blob heap" in the assembly metadata. The GC just ignores them when it encounters such a string object while it collects. Pretty similar to how string literals behave in the C language. Minus the bug that launched a billion crashes (a string literal is char* instead of const char* like it should be), you can never accidentally write to a string literal thanks to the immutability guarantee.

Upvotes: 7

Related Questions