Neden C programcıları 'yeni kullanımını en aza indirmek gerekir'?
Taşma soru ** 29 one of the comments Yığın rastladım şöyle diyor:
Çok
new
durdurunuz. Yeni bir yere kullanılan herhangi bir sebep göremiyorum yaptın. C değeri nesneleri oluşturabilir ve biri dili kullanarak için büyük bir avantaj. Ayırmak zorunda değilsiniz öbek her şeyi*. Java bir programcı gibi düşünmeyi bırak.
*Sabit yalnış anlatmış "yığın" alıntı.
Ne demek istediğini gerçekten emin değilim. Neden nesneleri C değeri ile mümkün olduğunca sık oluşturulmalıdır, ve dahili olarak ne fark eder? Cevap yanlış mı anladım?
CEVAP
İki yaygın olarak kullanılan bellek ayırma tekniği vardır: Otomatik ayırma ve dinamik ayırma. Genellikle, her biri için belleğe karşılık gelen bir bölge var: stack ve heap.
Yığın
Yığın her zaman sıralı bir şekilde bellek ayırır. Sana ters sırada belleği serbest bırakmak için bunu gerektirdiği için bunu yapmak olabilir (İlk, Son: FİLO). Bu, birçok programlama dillerinde yerel değişkenler için bellek ayırma tekniğidir. En az muhasebe gerektirdiğinden çok, çok hızlı ve ayırmak için bir sonraki Adres örtülü.
C , bu denirotomatik depolamadepolama otomatik olarak kapsam sonunda iddia etti. Geçerli kod bloğu yürütme ({}
kullanarak sınırlandırılmış) tamamlanır tamamlanmaz, Bu blok içinde tüm değişkenler için bellek otomatik olarak toplanır. Bu da şu an neredeyıkıcılarkaynağa temizlemek için çağırdı.
Yığın
Öbek daha esnek bir bellek ayırma modu için izin verir. Defter tutma daha karmaşık ve ayırma yavaştır. Örtülü bırakma noktası yok çünkü, hafıza el ile delete
delete[]
(free
C) kullanarak serbest bırakmalısınız. Ancak, örtülü bir çıkış noktası olmaması öbek esneklik anahtarıdır.
Dinamik ayırma kullanma nedenleri
Öbek kullanarak yavaş ve olası bellek sızıntısı veya bellek parçalanmasına neden olsa bile, daha az sınırlı olarak mükemmel dinamik ayırma için iyi kullanım örnekleri var.
İki önemli sebep dinamik ayırma kullanmak için:
Ne kadar derleme zamanında ihtiyacın olduğunu bilmiyorsun. Bir metin dizesi halinde dosyanın okurken örneğin, genellikle dosya ne kadar program bitene kadar ayırmaya karar veremezsin var, ne olduğunu bilmiyorum.
Geçerli blok ayrıldıktan sonra saklandığı bellek tahsis etmek istiyorum. Örneğin, bir dosyanın içeriğini gönderir 12* *bir fonksiyon yazmak isteyebilirsiniz. Yığın tüm dosya içeriğini saklamak olabilir olsa bile, bu durumda, bir işlevin dönüş ve ayrılan bellek bloğu devam edebilirsin.
Neden dinamik ayırma genellikle gereksizdir
C yapısı olarak adlandırılan düzgün bir şey varyıkıcı. Bu mekanizma, bir değişkeni yaşam ile kaynağı ömrü zamankinden kaynaklarını yönetmek için izin verir. Bu tekniği RAII denir ve C ayırt edici noktasıdır . "Sarar" içine nesneleri kaynakları. std::string
mükemmel bir örnektir. Bu parçacığı:
int main ( int argc, char* argv[] )
{
std::string program(argv[0]);
}
aslında ayırır bellek değişken bir miktar. std::string
nesne ayırır bellek yığını kullanarak ve yıkıcı serbest bırakır. Bu durumda, sen yaptındeğilel ile tüm kaynakları yönetmek için lazım ve hala dinamik bellek ayırma faydaları var.
Özellikle, bu parçasında anlamına gelir:
int main ( int argc, char* argv[] )
{
std::string * program = new std::string(argv[0]); // Bad!
delete program;
}
gereksiz dinamik bellek ayırma. Program daha yazmayı gerektirir (!) ve bellek ayırması için unutma riskini tanıttı. Hiçbir belirgin parası ile yapar.
Neden otomatik depolama mümkün olduğunca sık kullanmak gerekir
Temelde, son paragraf özetliyor. Mümkün olduğunca sık otomatik depolama kullanarak yapar programları:
- yazın daha hızlı;
- çalıştırıldığında daha hızlı;
- /kaynak sızıntısı bellek daha az eğilimli.
Bonus puan
Başvurulan söz konusu, ek endişeler vardır. Özellikle şu sınıf:
class Line {
public:
Line();
~Line();
std::string* mString;
};
Line::Line() {
mString = new std::string("foo_bar");
}
Line::~Line() {
delete mString;
}
Aslında şunu bir daha kullanmak çok daha riskli
class Line {
public:
Line();
std::string mString;
};
Line::Line() {
mString = "foo_bar";
// note: there is a cleaner way to write this.
}
Nedeni std::string
düzgün bir kopya kurucu tanımlar. Aşağıdaki programı deneyin:
int main ()
{
Line l1;
Line l2 = l1;
}
Orijinal sürümü kullanarak, bu program aynı dize üzerinde delete
iki kez kullanır gibi olası kalabilir. Değiştirilmiş bir sürümünü kullanarak Line
Her örnek kendi dize sahip olacakörnekkendi belleği ile , her iki program sonunda çıkacak.
Diğer notlar
RAII geniş kullanımı tüm yukarıdaki sebeplerden dolayı C En iyi yöntem olarak kabul edilir. Ancak, hemen belli olan ek bir yararı yoktur. Temel olarak, parçalarının toplamından daha iyi. Bütün mekanizmaoluşturur. Bu ölçekler.
Eğer bir yapı bloğu Line
sınıf kullanıyorsanız:
class Table
{
Line borders[4];
};
Sonra
int main ()
{
Table table;
}
std::string
örnekleri, dört Line
örnekleri, Table
örnek ve tüm dize içeriğini ve . ayırdığı dört ^em>her şey otomatik olarak yüklenecektir serbest.
Neden nesne yerine bir işaretçi kendis...
Neden dosyaları bir yeni satır ile bit...
.NET 4.0 yeni bir GAC var, neden?...
Neden basit bir beşgen kullanmaktır bi...
Neden eclipse yeni bir proje oluşturma...