Hatalar, hatalar, sorular - sayfa 2499

 
fxsaber :

Anlamak istiyorum.

veri hizalama değil

 Print ( sizeof (A)); // 2

görünüşe göre bu, sizeof() öğesinin dahili kullanımı dikkate alınarak yapılır, yani. sizeof() fiziksel belleği dikkate almaz, yalnızca her türü bayt cinsinden toplar

hizalama, "içe aktarılan dll işlevlerine geçmek için" yardımında yazıldığı gibi, verilerin fiziksel bellekteki konumudur - farklı derleyicilerde ve dillerde, veri türlerinin boyutu veya daha doğrusu depolanma biçimleri farklı olabilir. bellek, bu nedenle yapının her bir üyesinin "hücresinden çıkmaması" için struct A pack(4) kullanmanız gerekir - bayt

İşte makalede Habré'nin nasıl olduğu:

 struct Foo
{
     char ch;
     int value ;
};

1 bayt: ch

2 bayt: boş

3 bayt: boş                                          BU karakter ch;

4 bayt: boş


5 bayt: değer[0]

6 bayt: değer[1] BU     iç değer;      

7 bayt: değer[2]

8 bayt: değer[3]


 
Igor Makanu :

görünüşe göre bu, sizeof() öğesinin dahili kullanımı dikkate alınarak yapılır, yani. sizeof() fiziksel belleği dikkate almaz, yalnızca her türü bayt cinsinden toplar

Bu doğru değil

 struct A pack( 4 )
{
   short j;
   char i;
};

void OnStart ()
{
   Print ( sizeof (A)); // 4
}
 
fxsaber :

Bu doğru değil

daha sonra örneğiniz sizeof() yapısının bayt cinsinden "ağırlığını" doğru bir şekilde hesapladığını kontrol etti,

sadece fiziksel hafızayı kontrol etmek için kalır, ama bence sadece dll çağırırken çalışacak, geliştiricilerin hafızadaki verilerin depolanmasını optimize etmedikleri bir gerçek değil;) - yani. pack(4) kodda amacına uygun olarak kullanılmıyorsa, yürütülebilir kodda yoksayılabilir.

 
Igor Makanu :

daha sonra örneğiniz sizeof() yapısının bayt cinsinden "ağırlığını" doğru bir şekilde hesapladığını kontrol etti.

Öyleyse şu soru ortaya çıkıyor, hizalama gerçekte nasıl çalışıyor? Dokümantasyon ve Habr, algoritmayı örnekleriyle açıklamadı.

Igor Makanu :

sadece fiziksel hafızayı kontrol etmek için kalır, ama bence sadece dll çağırırken çalışacak, geliştiricilerin hafızadaki verilerin depolanmasını optimize etmedikleri bir gerçek değil;) - yani. pack(4) kodda amacına uygun olarak kullanılmıyorsa, yürütülebilir kodda yoksayılabilir.

Aynısı fiziksel bellek için de geçerlidir.
 struct A pack( 4 )
{
   short j;
   char i;
};

void OnStart ()
{
   Print ( sizeof (A)); // 4
  
   const int handle = FileOpen ( __FILE__ , FILE_WRITE | FILE_BIN );
  
   if (handle != INVALID_HANDLE )
  {
    A a = { 0 };
    
     FileWriteStruct (handle, a);
     Print ( FileTell (handle)); // 4
    
     FileClose (handle);
  }
}
 
fxsaber :

Öyleyse şu soru ortaya çıkıyor, hizalama gerçekte nasıl çalışıyor? Dokümantasyon ve Habr, algoritmayı örnekleriyle açıklamadı.

her şey belirli derleyiciye bağlıdır, muhtemelen pack( 4 ) kullanırken verilerin nasıl kaydedildiğini görmek için birlik içinde MQL'yi deneyebilirsiniz.

 
Igor Makanu :

her şey belirli derleyiciye bağlıdır, muhtemelen pack( 4 ) kullanırken verilerin nasıl kaydedildiğini görmek için birlik içinde MQL'yi deneyebilirsiniz.

Bunu yapmanın offsetof ve başka yolları vardır.


ZY Hizalama görevinin belirsizliği ortadan kaldırmaya hizmet ettiği ortaya çıktı. Ama kendi kullanımım için değil. Eh, açıkça görülüyor ki, bellek tüketimi ve görünüşe göre performans, alanların sırasına bağlı.

 
fxsaber :

ZY Hizalama görevinin belirsizliği ortadan kaldırmaya hizmet ettiği ortaya çıktı. Ama kendi kullanımım için değil.

ve bu " her şey belirli bir derleyiciye bağlıdır " - geliştiriciler genellikle diğerlerine göre geliştirmelerinin performansını artırmak için hileler kullanır, MQL'de kaynak kodu optimizasyonunu devre dışı bırakma gibi derleyici yönergeleri yoktur. - RAM yerel kodunun çalışmasında veya kullanımında farkı göremezsiniz


Not: Bir dosyaya yazma örneğinin kesinlikle her zaman doğru çalıştığından emin değilim, birisi geçenlerde MQL'nin bir dosyaya yazarken Win API tarafından kullanıldığını yazdı, API işlevleriyle uyumluluk için bazı varsayımlar olabilir - ancak bunlar benim tahminlerim, derleyici geliştiricisi değilim

 
fxsaber :

Bunu yapmanın offsetof ve başka yolları vardır.


ZY Hizalama görevinin belirsizliği ortadan kaldırmaya hizmet ettiği ortaya çıktı. Ama kendi kullanımım için değil. Bellek tüketiminin alanların sırasına bağlı olduğunu açıkça görebilirsiniz.

Yanlış yerde bir yeri kazıyorsunuz, hizalama sizin için hiç gerekli değil, işlemcinin buna ihtiyacı var, böylece bazı int iki önbellek satırına girmez. Doldurmanın yapılacağı yer düzenlenmemiştir ve derleyiciye bağlıdır, bu nedenle, dış dünyaya geçerken pack()'e güvenilemez, sadece manuel doldurma.

 
Vict :

Yanlış yerde bir yeri kazıyorsunuz, hizalama sizin için hiç gerekli değil, işlemcinin buna ihtiyacı var, böylece bazı int iki önbellek satırına girmez. Doldurmanın yapılacağı yer düzenlenmemiştir ve derleyiciye bağlıdır, bu nedenle, dış dünyaya geçerken pack()'e güvenilemez, sadece manuel doldurma.

Açık, hepinize teşekkürler.

 
fxsaber :

Anlamak istiyorum.

Ve belgeler açıkça söylüyorsa, anlaşılması gereken ne var?

Yapı adı tanımlayıcı olarak kullanılamaz (değişken veya işlev adı). MQL5'te yapı elemanlarının hizalanmadan birbirini takip ettiği unutulmamalıdır. C++ dilinde, komut kullanılarak derleyiciye böyle bir gösterge yapılır.

 #pragma pack( 1 )

Ve daha ileride...

Yani MQL5'te hiç hizalama yoktur.

Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
  • www.mql5.com
Структура является набором элементов произвольного типа (кроме типа void). Таким образом, структура объединяет логически связанные данные разных типов. Объявление структуры Имя структуры нельзя использовать в качестве идентификатора (имени переменной или функции). Следует иметь ввиду, что в MQL5 элементы структуры следуют непосредственно друг...