Dinamik Bellek (new/delete)
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 14 / 104.
Artık işaretçileri ve referansları anladığınıza göre, onları dinamik bellek ayırma ile işe koşalım. new ve delete operatörleri, çalışma zamanında yığında (heap) nesneler oluşturmanıza ve yok etmenize olanak tanır.
Bellek ayırmak ve buna işaret eden bir işaretçi almak için new kullanın:
int* num = new int; // Tek bir tamsayı ayır
*num = 42; // İşaretçi aracılığıyla değer ata
Player* player = new Player("Hero"); // Nesne ayırBelleği serbest bırakmak için her new ifadesinin eşleşen bir delete ifadesi olmalıdır:
delete num; // Tek bir nesneyi serbest bırak
delete player; // Yıkıcıyı çağırır, ardından belleği serbest bırakırDiziler için new[] ve delete[] kullanın:
int* scores = new int[5]; // 5 tam sayıdan oluşan dizi tahsis et
scores[0] = 100;
delete[] scores; // Diziyi serbest bırak - köşeli parantezlere dikkat edin!Kaçınılması gereken yaygın hatalar:
// Bellek sızıntısı - silmeyi unuttunuz
int* ptr = new int(10);
ptr = new int(20); // İlk tahsise erişim kaybedildi!
// Sarkan işaretçi (Dangling pointer) - sildikten sonra kullanma
delete ptr;
*ptr = 5; // Tanımsız davranış!
// Uyumsuz silme
int* arr = new int[10];
delete arr; // Yanlış! delete[] olmalıSildikten sonra, yanlışlıkla yeniden kullanımı önlemek için işaretçileri nullptr olarak ayarlayın. Manuel bellek yönetimi hataya açıktır; bu nedenle modern C++, bir sonraki adımda inceleyeceğimiz akıllı işaretçileri tercih eder.
Görev
Kolaynew ve delete ile dinamik bellek ayırmayı gösteren basit bir mesaj depolama sistemi oluşturalım.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
MessageBox.h: Bir mesaj dizisini dinamik olarak yöneten birMessageBoxsınıfı tanımlayın. Sınıf şunlara sahip olmalıdır:- Dinamik olarak ayrılmış bir dizge dizisine yönelik özel bir işaretçi
- Mevcut mesaj sayısını izleyen özel bir tamsayı
- Maksimum kapasiteyi tutan özel bir tamsayı
- Bir kapasite alan ve diziyi
new[]kullanarak ayıran bir kurucu - Belleği
delete[]kullanarak düzgün şekilde serbest bırakan ve"MessageBox destroyed"yazdıran bir yıkıcı - Yer varsa bir mesaj ekleyen, başarılı olduğunda
addMessage(string msg)veya kapasite doluysatruedöndüren birfalseyöntemi - Depolanan her mesajı kendi satırında yazdıran bir
printAll()yöntemi
main.cpp: Girdiden bir kapasite değeri ve mesaj sayısı okuyun. Ardından bu kadar mesaj dizgesini okuyun. ÖbekteMessageBoxkullanarak birnewoluşturun, tüm mesajları buna ekleyin,printAll()çağrısını yapın ve ardından belleği serbest bırakmak için MessageBox'ı düzgün şekilde silin.
Girdi biçimi şöyle olacaktır:
- İlk satır: kapasite (tamsayı)
- İkinci satır: eklenecek mesaj sayısı (tamsayı)
- Sonraki satırlar: satır başına bir mesaj
Unutmayın: her new için eşleşen bir delete ve her new[] için eşleşen bir delete[] gerekir. Sildikten sonra işaretçileri nullptr olarak ayarlamak iyi bir uygulamadır.
Başlık dosyanızı main.cpp içine #include "MessageBox.h" kullanarak ekleyin.
Kendin dene
#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;
int main() {
int capacity;
int numMessages;
// Kapasiteyi ve mesaj sayısını oku
cin >> capacity;
cin >> numMessages;
cin.ignore(); // Sayıdan sonraki yeni satır karakterini temizle
// TODO: new kullanarak heap üzerinde bir MessageBox oluştur
// TODO: Tüm mesajları oku ve MessageBox'a ekle
for (int i = 0; i < numMessages; i++) {
string message;
getline(cin, message);
// Mesajı MessageBox'a ekle
}
// TODO: Tüm mesajları görüntülemek için printAll() fonksiyonunu çağır
// TODO: Belleği boşaltmak için MessageBox'ı sil
// Sildikten sonra işaretçiyi nullptr olarak ayarlamayı unutma
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi