2010-08-02 16 views
6

Garip bir sorunla karşılaşıyorum, biraz izleyebildim ama yine de nedenini göremiyorum. Belki birileri biraz ışık tutabilir mi?Gömülü bir platformda konu sınıfı bellek ayırma tuhaflığı

PPCgnu604 takım zinciri ile C++ 'da gelişen VxWorks 5.5'in üstünde bir PowerPC işlemcisinde çalışıyorum.

Bir sınıf şöyle var: Başvurum başlatıldığında

class MyClass 
{ 
    public: 
    void run(void); 
    private: 
    CommandMesssageClass command; 
    StatusMessageClass status; 
}; 

, dinamik Sınıfım bir örneğini tahsis ve onun "run" işlevine işaret eden bir iş parçacığı doğacaktır. Esasen sadece komutlar için oylama yapar ve makbuz üzerine bir durum geri verir.

Bunun, sınıfın kırpılmış bir sürümü olduğunu unutmayın. Kısıtlılık için dışarıda bırakılan bir dizi başka yöntem ve değişken vardır.

Gördüğüm sorun, hem komut hem de durum iletileri özel sınıf üyeleri olarak tanımlandığında, dinamik bellek ayırması olmamasına rağmen, kullanılabilir baytlarda bellekte bir değişiklik olacaktır. Bu önemlidir çünkü bu, deterministik ve hız-güvenli bir prosedür olması gereken şeylerde ortaya çıkar.

İleti bildirimlerinden birini veya her ikisini de çalıştırma işlevine taşırsam, ek bir ayırma olmadan iyi çalışır!

C++ bildirimleri ve bellek ayırma konusundaki anlayışımda temel bir şey eksik olmalıyım. Anlayışım, dinamik olarak benimsemediğim bir sınıf örneğinin, oluşturulduğunda yığında (tüm üye değişkenleri de dahil olmak üzere) tamamen tahsis edilmesidir. Burada gördüğüm fark, mesaj bildirimlerini çalışma fonksiyonuna taşımak yerine onları yığına koyar. Bu durumda yığın, sınıfın tüm büyüklüğüne eşlik edecek kadar büyüktür. Belirli bölümler kullanılıncaya kadar neden yeterince bellek ayırmıyor gibi görünüyor?

İleti sınıfları kendi başına dinamik ayırma yapmaz. (Ve eğer yapmışlarsa, beyanın hareket etmesini beklerdim bu durumda davranışı değiştirmezdim ve hala yığın büyüklüğünde bir değişiklik görecektim.)

Bellek ayırmasını izlemek için aşağıdakileri kullanıyorum VxWorks memLib (veya memPartLib) çağrı:

memPartInfoGet(memSysPartId, &partitionStatus); 
... 
bytesFree = partitionStatus.numBytesFree; 

Düzenleme:

sınıfı bir nesne instansiated ve bir başlatma yordamında başlatıldı ve kod oranı için güvenli işleme girer, değerlendirmektir. Bu süre zarfında, bir komut satırı mesajının bir seri satır üzerinden (Komut veya Durum mesajı nesnesi ile ilk etkileşim) alınması üzerine, ilave bellek ayrılır (veya daha az sayıda bayt azalması). Bu kötüdür çünkü dinamik bellek ayırma deterministik değildir.

Sınıf değişkenlerini tanımladığım gibi taşıyarak problemden kurtuldum.

+0

Sorununuzun ne olduğu tamamen anlaşılır değil, yığınları sınıftaki üyelere göre daha fazla bellek ayırmanız mı, yoksa kullanılan belleğin bu durumlardan birinde zamanla değiştiği mi? – nos

+1

Genel öğeleri üyeler kaldırdığınızda sizeof (MyClass) değişir mi? Ve bellek ayırma ne kadar değişir? –

+1

* Tahsis ne zaman değiştirilir? Daha küçük sınıf nesneleri, yığıntaki boş bir blokta daha kolay bir zamana sahiptir. –

cevap

2

C++ bildirimleri ve bellek tahsisi benim anlayış temel bir şey eksik gerekir.

Sanmıyorum. Yukarıda beklediğiniz her şey doğrudur - oyun programcıları sürekli bu davranışa bel bağlamaktadır.:-)

Neden belirli kısımları kullanılmaktadır kadar yeterli bellek ayrılırken olmamak görünüyor?

Sınıfın bağırsaklarını kıskanmak için dışarıda bıraktınız. Ben benzer sorunları hata ayıklama bazı deneyimler yaşadım ve en iyi tahminim orada bir yerde bir kütüphane fonksiyonu, bilmiyorum, bir çalışma zamanı ayırma yapmak. Diğer bir deyişle, çalışma zamanı ayırma her iki durumda da vardır, ancak iki farklı boyuttaki MyClass malloc havuzlarının farklı şekilde doldurulduğu anlamına gelir. Nesneleri run() içindeki yığına taşıyarak ancak MyClass'ı aynı boyuta getirerek kanıtlayabilirsiniz. Hala ücretsiz mem damla görüyorsanız, o zaman bu nesnelerin yığın veya yığın üzerinde olup olmadığı ile ilgili bir şey yok ... bu MyClass boyutu nedeniyle gerçekleşen ikincil bir etkisidir.

Unutmayın, malloc gizlidir - çoğu uygulama, malloc'a yapılan her çağrı için bire bir ayırma yapmaz. Bunun yerine hafızayı bir havuzda fazla tahsis eder ve saklar ve gerektiğinde bu havuzları büyütür.

Takım zincirinize aşina değilim, ancak yerleşik sistemlerdeki beklenmedik küçük ayırmalar için tipik şüpheler, ctype işlevlerini (yerel) ve tarih/saat işlevlerini (saat dilimi) içerir.