Strings auf CRT Heap und Stack



  • Hey,

    String ^einText = "hello world";
    String ^einAndererText = gcnew String("another world");
    

    Wenn der zweite String auf dem Heap erstellt wird, wo liegt dann der erste? Wo sind hier die Unterschiede?

    Gruss
    ben



  • Ein "String" ist was ganz besonderes... es ist eine Mischung aus GC-Heap Objekt und Interned...
    Er ist "immutable" aber verhält sich doch so als wäre er veränderbar.

    Aber bzgl. dem Code: Beide Zeilen erzeugen genau den gleichen IL-Code... der Compiler fügt automatisch ein "gcnew" im ersten Fall ein...



  • Jochen Kalmbach schrieb:

    Aber bzgl. dem Code: Beide Zeilen erzeugen genau den gleichen IL-Code... der Compiler fügt automatisch ein "gcnew" im ersten Fall ein...

    Danke für die Erklärung!

    Gruss
    ben



  • Jochen Kalmbach schrieb:

    der Compiler fügt automatisch ein "gcnew" im ersten Fall ein...

    Ist das immer so?

    ref class CMyClass
    {
    public:
    	int	value;
    
    public:
    	CMyClass(void);
    };
    
    CMyClass c;
      c.value = 0;
    

    und

    CMyClass ^c = gcnew CMyClass();
        c->value = 0;
    

    erzeugen auch denselben IL-Code

    .method assembly static int32  main(string[] args) cil managed
    {
      // Code size       21 (0x15)
      .maxstack  2
      .locals ([0] class CMyClass c,
               [1] int32 V_1)
      IL_0000:  ldc.i4.0
      IL_0001:  stloc.1
      IL_0002:  ldnull
      IL_0003:  stloc.0
      IL_0004:  newobj     instance void CMyClass::.ctor()
      IL_0009:  stloc.0
      IL_000a:  ldloc.0
      IL_000b:  ldc.i4.0
      IL_000c:  stfld      int32 CMyClass::'value'
      IL_0011:  ldc.i4.0
      IL_0012:  stloc.1
      IL_0013:  ldloc.1
      IL_0014:  ret
    } // end of method 'Global Functions'::main
    

    Gibt es eine Dokumentation wo man solche einfachen Dinge mal nachlesen kann?

    Gruss
    ben_



  • Ich glaube der Unterschied bei der Stack-Semantic liegt eher bei der deterministischen Zerstörung der Objekte:

    // StackSemantic.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    
    using namespace System;
    
    ref class CMyClass
    {
    public:
      CMyClass()
      {
        Console::WriteLine(__FUNCSIG__);
      }
      ~CMyClass()
      {
        Console::WriteLine(__FUNCSIG__);
      }
    protected:
      !CMyClass()
      {
        Console::WriteLine(__FUNCSIG__);
      }
    };
    
    int main(array<System::String ^> ^args)
    {
      CMyClass c1;
      CMyClass ^c2 = gcnew CMyClass();
      CMyClass ^c3 = gcnew CMyClass();
    
      delete c2;
      Console::WriteLine(L"Nach delete");
    
      return 0;
    }
    

    ergibt

    __clrcall CMyClass::CMyClass(void)
    __clrcall CMyClass::CMyClass(void)
    __clrcall CMyClass::CMyClass(void)
    __clrcall CMyClass::~CMyClass(void)
    Nach delete
    __clrcall CMyClass::~CMyClass(void)
    __clrcall CMyClass::!CMyClass(void)
    

    Bei c2 wird der Destruktor beim delete aufgerufen. Der von c1 wird aufgerufen, wenn es aus dem Scope geht.

    Bei c3 wird dagegen der Finalizer aufgerufen, wenn der GC das Objekt zerstört.



  • Gruss wird immer noch Gruß geschrieben, fang erstmal damit an.



  • nn schrieb:

    Ich glaube der Unterschied bei der Stack-Semantic liegt eher bei der deterministischen Zerstörung der Objekte:

    Vielleicht ist es Referenzvariablen aus C# vergleichbar, die implizit auf dem CRT-Heap erstellt werden. (ref class)

    gRuSs
    ben



  • Hallo,

    der Vollständigkeithalber hier noch die Erkärung aus der MSDN:

    When you create an instance of a reference type using stack semantics, the compiler does internally create the instance on the garbage collected heap (using gcnew).

    Quelle: http://msdn.microsoft.com/de-de/library/ms177191.aspx

    Gruss
    ben


Anmelden zum Antworten