SORU
16 NİSAN 2012, PAZARTESİ


C bir dize'\0' sonra bellek ne olacak?

Şaşırtıcı derecede basit/aptal/temel soru, ama hiçbir fikrim yok: Varsayalım istiyorum dönmek kullanıcının görevim bir C-string, kimin uzunluğu bilmiyorum başında fonksiyonu. Sadece bir üst başında uzunluğuna bağlı yer olabilir, ve, işleme bağlı olarak, boyutunu küçült.

Soru, orada hiçbir şey yeterli yığın alanı (üst sınır) ayrılırken ve sonra Dize sonlandırıcı ile yanlış bunun gayet kısa işlem sırasında. ben İse, yani '\0' ayrılan bellek, (.) ortasına sopa free() hala düzgün çalışması, ve (b.) '\0' önemsiz olur? sonra boşluk yok '\0' eklenir, bellek sadece geri alabilir mi veya free() çağrılana kadar orada oturan işgal alanı mı? Zaman gerekli alanı bilişim malloc çağırmadan önce genellikle kötü avansa programlama kaydetmek için bu asılı boşluk bırak, programlama tarzı mı?

Bu bazı bağlam vermek için, diyelim ardışık yinelemeler, bu gibi kaldırmak istiyorum ki:

"!! Merhaba oOOOo" giriş -->çıkış "Helo oOo !"

... ve bazı ön-bilgi işlem boyutu benim operasyon sonucunda ben nasıl gösteren kod aşağıda, etkili bir performans yığın boyutunu hakkı elde etmek için iki kez işlem.

char* RemoveChains(const char* str)
{
    if (str == NULL) {
        return NULL;
    }
    if (strlen(str) == 0) {
        char* outstr = (char*)malloc(1);
        *outstr = '\0';
        return outstr;
    }
    const char* original = str; // for reuse
    char prev = *str  ;       // [prev][str][str 1]...
    unsigned int outlen = 1;  // first char auto-counted

    // Determine length necessary by mimicking processing
    while (*str) {
        if (*str != prev) { // new char encountered
              outlen;
            prev = *str; // restart chain
        }
          str; // step pointer along input
    }

    // Declare new string to be perfect size
    char* outstr = (char*)malloc(outlen   1);
    outstr[outlen] = '\0';
    outstr[0] = original[0];
    outlen = 1;

    // Construct output
    prev = *original  ;
    while (*original) {
        if (*original != prev) {
            outstr[outlen  ] = *original;
            prev = *original;
        }
          original;
    }
    return outstr;
}

CEVAP
16 NİSAN 2012, PAZARTESİ


Eğer bir '\0' ayrılmış bellek ortasına . soksam

(bir.) () ücretsiz hala düzgün çalışmıyor

Evet.

(b.) '\0' önemsiz olur? sonra boşluk yok '\0' eklenir, bellek sadece döndürdü mı, yoksa oturarak işgal alanı kadar özgür() denir.

Bağlıdır. Genellikle, zaman ayırmak büyük miktarda yığın alanı, sistem ilk sanal adres alanı ayırır - seni yazmaya sayfalar için bazı fiziksel bellek atanır geri (ve daha sonra takas için zaman disk işletim sistemi sanal bellek desteği). Ünlü, ayırma sanal adres alanı ve gerçek fiziksel/takas alanı savurgan arasındaki bu ayrım, seyrek diziler OSs makul bellek verimli olmasını sağlar.

Şimdi, bu sanal adresleme ve çağrı parçalı bellek sayfa boyutlarda olduğunu 4k, 8k, 16k... olabilir mi? En takarız sayfa boyutunu öğrenmek için arayabilirsiniz bir işlev. Yani yapıyorsan çok küçük ayırmalarını sonra yuvarlama için sayfa boyutları savurgan olduğunu, ve eğer bir sınırlı adres alanı göreli miktarda hafıza gerçekten ihtiyacımız kullanın bağlı olarak sanal adresleme yolu tarif yukarıda olmayacak ölçek (örneğin, 4 GB RAM ile 32-bit adresleme). Diğer taraftan, eğer bir 64-bit işlem, çalışan ki 32 GB RAM, ve yapmak nispeten az insan bu dize ayırma, muazzam bir miktar sanal adres alanı için oyun ve yuvarlama için sayfa boyutu olmayacak miktarda fazla.

Ama - not arasındaki fark yazı boyunca tampon sonra sona eriyor biraz önceki nokta (bu durumda, bir zamanların yazılı-bellek olacak yedekleme bellek ve sonunda takas) karşı sahip büyük bir tampon olan sadece yazmak için önce biraz sonra Sonlandır (bu durumda destek bellek sadece tahsis için kullanılan alan yuvarlanır sayfa boyutu).

Bu da kayda değer işaret eden birçok işletim sistemleri yığın bellek olmayabilir iade İşletim Sistemi kadar işlemi sonlandırır: bunun yerine, malloc/free Kütüphanesi bildirir OS ne zaman ihtiyacı büyür öbek (örneğin kullanarak sbrk() UNİX veya VirtualAlloc() Windows). Bu anlamda, free() hafıza yeniden kullanım, işlem için ama diğer süreçleri kullanmak için ücretsiz. Bazı İşletim Sistemleri, bu, örneğin, çok büyük ayırma için ayrı ve bağımsız olarak releasble bellek bölgesi kullanılarak optimize.

Zaman gerekli alanı bilişim malloc çağırmadan önce genellikle kötü avansa programlama kaydetmek için bu asılı boşluk bırak, programlama tarzı mı?

Yine uğraşıyoruz bağlıdır. Eğer orada pek çok göreli sanal adres alanı / RAM - açıkça izin bellek Kütüphanesi bilmezler her başlangıçta istenen bellek gerçekten gerekli kullanma realloc(), ya da sen bile kullanmak strdup() ayırmak için yeni bir blok daha sıkı bağlı gerçek ihtiyaçlarına (free() orijinal) - bağlı malloc/ücretsiz kütüphane uygulaması işe yarar daha iyi ya da daha kötü, ama çok az sayıda uygulama olacağını önemli ölçüde etkilenen bir fark.

Bazen kodunuzu olabilir bir kütüphane nerede edemezsin sanırım bir kaç dize örnekleri arama uygulama yönetme - böyle durumlarda daha iyi sağlamak için daha yavaş bir davranışı asla ... çok kötü... çok yalın doğru küçülen bellek blokları için uygun dize veri (bir ilave işlemler çok etkilemez koca-Ey verimliliği) yerine sahip bilinmeyen bir oran orijinal dize arabellek boşa (bir patolojik vaka, sıfır ya da bir karakter kullanılmış sonra keyfi büyük ayırma). Performans optimizasyonu olarak yalnızca unusued alanı ^ * dönen rahatsız olabilir . = kullanılan alan ayar tat, ya da onu arayan yapılandırılabilir.

Başka bir haber::

Aşağı realloc daha uzun sürer yargılamak için geliyor, ya önişleme boyutu tayini?

Eğer performans sizin için en önemli öncelik ise, o zaman evet - profil almak istiyorum. Eğer CPU bağlı iseniz, o zaman genel bir kural "" ve sağ büyüklükte bir ayırma-sadece daha az parçalanma var ve berbat. ne isabet önişleme al Bu mücadele, eğer bazı işlev için özel önişleme bir mod yazmak için varsa - bu fazladan "yüzey hataları ve kod için" korumak. (Bu ticaret-off karardır yaygın gerektiğinde uygulama kendi asprintf() snprintf() ama en azından güvenebilirsin snprintf() olarak belgelenmiş ve yok şahsen olmasını sağlamak.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AndyMcMillinTV

    AndyMcMillin

    6 HAZİRAN 2007
  • CHISTOSITOJAJA

    CHISTOSITOJA

    27 HAZİRAN 2010
  • CruzerLite

    CruzerLite

    1 EKİM 2011