堆栈或堆上的这个对象?

Ahm*_*med 1 .net c++-cli heap-memory

在C++/CLI中,以下两个是相同还是不同?

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

System::String ^source= gcnew System::String("Hello World");
Run Code Online (Sandbox Code Playgroud)

第一个是堆栈,第二个堆栈吗?
或者他们都在堆?
.Net对象我认为只有引用它们不能在堆栈上创建,这与C++允许我们不同.有人可以解释一下吗?

Han*_*ant 7

字符串既不存储在堆栈上,也不存储在堆中.这个故事有点令人费解.

考虑它的通常有用的方法是引用类型对象始终存储在GC堆上.非常类似于C++(又名std :: string),像字符串这样的可变长度对象需要使用免费存储来分配正确的内存量.在std :: string中模拟可能的微优化,可以在std :: string对象中存储非常短的字符串.但通常std :: string对象本身可以在堆栈上分配,字符串内容在堆上分配.就像source在堆栈上一样,只是一个垃圾收集器可以找回的普通指针.

C语言允许在堆栈上存储字符串内容,但您必须预先猜测所需的字符串缓冲区长度.发起成千上万的恶意软件攻击,字符串缓冲区溢出是一种标准技术,可以搞乱程序的堆栈帧并改变函数返回值.不是.NET方式.AC语言编译器不具备做这样的说法,他们只是非常普遍的事情.

但是在你给出的例子中并不是直截了当的.语句之间没有区别,字符串内容既不在堆栈上也不在堆上分配.CLR是大量微优化,以利用CLI规范的优势,描述如何串的标准必须在符合的CLR实现的行为.

它利用了字符串对象不可变的属性.这允许称为实习的优化.字符串对象的外观和行为与存储在GC堆上的行为相似.但事实并非如此,对象内容直接从程序集的内存映射图像中读取.存储在程序集元数据中的"blob堆"中.当GC收集时遇到这样的字符串对象时,GC会忽略它们.非常类似于字符串文字在C语言中的行为方式.减去发起十亿次崩溃的错误(字符串文字char*而不是const char*它应该是这样),由于不变性保证,你永远不会意外地写入字符串文字.