2016-03-25 30 views
0

Bir Huffman kodlayıcı uygularım. Huffman ağaçları öncelik sırasını kullanarak aşağıdan yukarıya inşa edilmiştir. Diğer iki düğümün işaretçileri olan basit bir düğüm sınıfım var. ağacı oluşturur döngü:düğüm döngü içinde kendi kendine referans döngü

while(q.size() > 1) 
{ 
    huffnode n1 = q.top(); 
    q.pop(); 
    huffnode n2 = q.top(); 
    q.pop(); 

    q.push(huffnode((char)0, n1.freq+n2.freq, &n1, &n2)); 
} 

döngü sona kalan Düğüm ağacı köküdür.

Bu kod yeterince masum görünmüyor, fakat benim test girişimde, kökü sağ çocuğun, kuyruğundan atılan iki düğüm yerine kökün sol çocuğunun kendisine ve sol çocuğuna işaret ettiği bir ağaç veriyor. Kuyruğun doğru şekilde sıralandığından emin oldum.

Neler oluyor n1 ve n2, hata ayıklayıcısında görüldüğü gibi her zaman aynı adrese sahip yerel değişkenlerdir. Yeni bir node itildiğinde, bu adreslere işaret eder. Bu düğüm daha sonra atılırsa, kopyası, bir tanesi işaret ettiği adreslerden birine girer, o zaman kendini işaret eder.

Bunu nasıl düzeltmeliyim? N1 ve n2 işaretçileri yapamıyorum çünkü bu nedenle 0 (bir) bir const başvuru döndürüyor ve bir const referansına ya da const işaretçisine topun sonucunu atamak, sıra değişmez hale getirdiğinden, const olması gerekiyordu.

+1

adresleri 've n1, & 'while' döngü kaldıktan sonra n2' geçersiz kılınır. Sarkan işaretçilerle uğraşıyorsunuz (ne yaparsanız yapın). Bu durumda –

+0

, o zaman neden döngü sona erdikten sonra kök göstergelerini takip edebilirim? – BenK

cevap

2

Kıvırcık parantezleriniz {} olduğunda, yeni bir kapsamdasınız. ve bu kapsamda beyan edilen değişkenler bu kapsamda yereldir ve sadece bu kapsamda geçerlidir. Kapsam sona erdiğinde, döngü sizin için yinelenen her döngü olduğunda, kapsam kaybolur ve bu kapsamdaki değişkenler yok edilir ve artık yoktur.

İşaretçiyi kapsam dışı olan bir değişkene kaydetmek, işaretçiyi işaretlemeyi denediğinizde tanımsız davranış neden olur.

0

C++, çöp toplamaya sahip değildir ve bunu söylemediğiniz sürece öbekte nesneleri ayırmaz - belleğinizi kendiniz yönetmeniz gerekir.

Dinamik olarak ayrılan bir ağaç oluşturmak istiyorsanız, düğümlerinizi new veya bazı üst düzey kütüphane olanaklarını kullanarak yığın üzerinde açıkça ayırmanız gerekir. Onlara daha fazla referans olmadığını bilerek yok olduklarından emin olmanız gerekir.

Diğerleri de söylediğim gibi

, sizin huffnode değişkenler n1 ve n2 yerel değişkenler ve bunlar kapsam dışında gidince yok edilir (ki, senin while döngünün her geçiş).

+0

Yerel değişkenlerin kapsam dışında kaldıklarında yok olduklarını biliyorum ancak hata ayıklayıcım her yineleme işleminde her zaman aynı adreslere sahip olduklarını gösteriyor. Belki de derleyici bunu bir döngü optimizasyonu olarak yapar, böylece programın her yineleme için pahalı bellek talepleri yapması gerekmez. Buradaki nokta, n1 ve n2'nin her yinelemenin sonunda yok edilmesinin, bir sonraki iterasyonun başında aynı belleği kullanamayacakları anlamına gelmez. – BenK

+1

Ancak onlardan bir ağaç oluşturmak istiyorsanız, aynı belleği yeniden kullanamazsınız - her düğüm için ayrı bir nesne ayırmanız gerekir! C++'da, bir yerel nesne değişkeni bildirirseniz, * gerçek nesne * yığında saklanır ve * kapsam dışına çıktığında * yok olur. Bu, tüm nesneleri yığınlarına ayıran, yalnızca yerel değişkenlerindeki referansları depolayan ve ayrılan nesneleri çöp toplayana kadar koruyacak olan Java'dan farklıdır. – comingstorm

+1

Yani, her ayrı düğümü tahsis etmeniz gerekiyor ('new' kullanarak). Yerel değişkenleriniz sonuçta elde edilen yığın ayrılan nesnelere * işaretçi * (bir çeşit) olmalıdır. – comingstorm

0

comingstorm haklı. new kullanmam gerekiyor.

sabit kod

while(q.size() > 1) 
{ 
    huffnode* n1 = new huffnode(q.top().data, q.top().freq, q.top().left, q.top().right); 
    q.pop(); 
    huffnode* n2 = new huffnode(q.top().data, q.top().freq, q.top().left, q.top().right); 
    q.pop(); 

    q.push(huffnode((char)0, n1->freq + n2->freq, n1, n2)); 
}