2013-08-16 27 views
6

Std :: çifti bir ikili dosyaya kaydedilmeye çalışıldığında std :: pair ile gerçekleşen hoş olmayan bir şey fark ettim: std :: çifti bir sözcüğe hizalanır. İşlemci verimliliği açısından yararlı olabilir, ancak daha fazla depolama alanı gerektirir, bu yüzden std :: çifti için hizalama modunu 1 bayta dönüştürmek istiyorum. Benim derleyici 2012.std :: eş <U,V> hizalama denetimi

#include <iostream> 

int main() 
{ 
    struct S_a { double a; size_t b; }; 

#pragma pack(1) 
    struct S_wa { double a; size_t b; }; 

    std::cout << sizeof(size_t) << '\n';       // 4 
    std::cout << sizeof(double) << '\n';       // 8 
    std::cout << sizeof(std::pair< size_t, size_t >) << '\n';  // 8 
    std::cout << sizeof(std::pair< double, size_t >) << '\n';  // 16 - bad 
    std::cout << sizeof(S_wa) << '\n';       // 12 - good 
    std::cout << sizeof(S_a) << '\n';        // 16 
    std::cout << sizeof(std::pair< double, double >) << '\n';  // 16 
} 

Bu çalıştı ++ MS VC, ama çalışmıyor:

class xxx 
{ 
    T1 _t1; 
    T2 _t2; 
}; 

hizalanması:

#pragma pack(1) 
    typedef std::pair< double, size_t > Q; 

    std::cout << sizeof(Q) << '\n';        // 16 
+1

, değiştirmeyi deneyin * C/C++ -> Kod Üretimi -> Struct Üye Hizalama * seçeneği ('/ Zp1') – Praetorian

+1

yerine daha iyi olmaz, sizin çalışma zamanı üzerinde vidalama sadece idare özel fonksiyonlar yazmaya ikili nesneleri okumak ve yazmak –

cevap

4

Üzgünüz, bu durumda pack pragma sizin için çalışmayacaktır. Bu sorunların TÜM SORUNLARINA neden olabilirsiniz. Bunlardan biri, özellikle düşük seviyeli olan belirli API'ların, verilerin belirli bir şekilde hizalanmasını beklemesidir. Bunların hepsi, olmadığı durumla başa çıkmak için yeterince akıllı değildir; Bu belirsiz çökmesine yol açabilir.

Eğer gerçekten nesne böyle Serileştirilecek istiyorsanız, std::pair<U,V> kendiniz seri (sadece örnek) işlemek:

template<typename U, typename V> 
void paircpy(char *dest, const std::pair<U, V> &pair) { 
    memcpy(buffer, &pair.first, sizeof(U)); 
    memcpy(buffer + sizeof(U), &pair.second, sizeof(V)); 
} 

Sen memcpy yok veri türleri için özel olaya el isteyeyim iyi.

gerçekten yapmalıyım, herhangi bir ciddi proje için, bunlar geri alınabilir konum ve zarif imzalı veri türleri için yüzen noktası, farklı kodlamaları gibi şeyler işlemek, böylece taşınabilir bir şekilde işaretçiler nesneleri tefrika olduğunu, diziler, STL Nesnelerin belleğinin basit bir dökümü mümkün olmayan veya yetersiz olan konteynerler ve başka herhangi bir şey.

C++ FAQ numaralı telefonu okuyun ve kendi seri hale getirme modüllerinizi geliştirin; bunlar, nesnenin dosya için bellek içi temsilini boşaltmaktan daha fazlasıdır.

Alternatif olarak, veri türlerini serialising için önceden paketlenmiş taşınabilir çözüm kullanabilirsiniz böyle

+0

Tamam. Ben diskte dosya ve zaten bazı sıralanırken yapmak bağlı bir std :: vector, kolları bir sınıf ArrayFile var. Bunun bir bellek ayırma değiştirmeden, açıkça ArrayFile T = std :: çifti için uzmanlaşmak ve orada alighnment azaltmak için doğru olur, düşünüyorum. tamam? '' _CRT_PACKING' makro kullanarak kendi ambalajını tanımlayan 'çünkü #include ' önce –

+0

'# Pragma pak' hiçbir şey yapmaz. –

+0

@JonathanPotter düzeltildi. – Anthony

6

A std::pair temelde aşağı düşürür iki üye, yalnızca bir örneği örneklemek için kullanıldığında, şablon tanımlandığında, yürürlükteki hizalama tarafından tanımlanır.

STL'nin Microsoft uygulaması, tüm STL bileşenleri için kullanılan ambalajı tanımlamak için _CRT_PACKING sembolünü kullanır. Varsayılan olarak, paket 8'e ayarlıdır. Bu sembolü std::pair (<utility>) tanımlayan başlığı dahil etmeden önce kendiniz tanımlarsanız, ambalajı teorik olarak geçersiz kılabilir ve kendiniz ayarlayabilirsiniz.

Arama kütüphaneleri veya standart paketlemeyi kabul eden diğer kodlarla karşılaşabileceğiniz olası sorunlardan haberdar olun.

0
olarak

Tamam, b olabilir ya da olmayabilir tamamen farklı 'çözüm' e iyi bir fikir, ama hey eğer işe yaramazsa seni kimden bilemem. Diğer cevaplarla aynı uyarılarla birlikte gelir, ancak zehirleri seçmenize ve seçmenize izin verir.

, söz konusu tanım için Pragma paketi kullanarak, önemsediğiniz türleri için ex std::pair kısmi ihtisas yapın. char ve int için: tanımı bir yere dokunabilir ile

namespace std { 
#pragma pack(/* ... whatever you want ... */) 
template<> struct pair<char,int> { 
    char first; 
    int second; 
}; 
} 

, sen paketleme etkileyebilir. Yine de, tüm ilgili türler için bunu yapmaya istekli olmanız ve diğer posterlerin bahsettiği uyarıları aklınızda bulundurmanız yeterlidir.

ve orada kullandığınız kütüphane deli ve lib geri kalanı bağlıdır pair daha fazla şeyler koymak için karar küçük bir şans var, ama muhtemelen

bu konuda endişelenmenize gerek yok proje özellikleri altında