1

Dinamik bellek ayırma ile ilgili bir sorunum var gibi görünüyor.C++: Sınıf nesnesi türetildiğinde dinamik belleği ayırma

Aşağıda, void name(const char* name) yöntemini kullanarak dinamik olarak ayrılacak bir ad değişkeninin işaretçisini içeren türetilmiş bir sınıf göreceksiniz. İşlev, nesne oluşturulduğunda ürün sınıfı için bir ad belirleyen Ürün yapıcısı tarafından çalıştırılır.

namespace sict { 
    class Product :public Streamable { 

    char* name_; 

public: 

    Product(const char* name); 
    virtual ~Product(); 

    void name(const char* name); 

} 

Ve burada bir argüman yapıcısı ile birlikte adı işlevi kendisidir: İşte sınıfı var

void sict::Product::name(const char * name) { 
    int g = strlen(name); 
    name_ = new char[g]; 
    strncpy(name_, name, g); 
    name_[g] = 0; 
} 

Product::~Product() { 
    delete [] name_; 
    name_ = nullptr; 
} 

bu kod Çıkan zaman barışçıl onu yok ardından oluşturulan nesnenin yeterince yetenekli görünüyor Bana göre Çalıştığı işlevin kapsamı. Ancak, işlev sona erdiğinde ve yıkıcı çalıştırıldığında, program delete [] name_'da donuyor/çöküyor. Programın Visual Studio'nun derleyicisinde çalıştırılması, belirli bir hata içermiyor gibi görünüyor (programın donması dışında), ancak gcc derleyicisi bir çeşit yığın bozulması algıladı. Bunun neden olduğunu bilen var mı?

+6

' name_ [g] = 0 bkz. Onaylamak için 'g'' strlen (isim) + 1 '' i değiştirmeyi deneyin. Bu C++ olduğundan, ['std :: string'] (http://en.cppreference.com/w/cpp/string/basic_string) kullanarak daha iyi durumda olacak ve sizin için bellek yönetimini ele alalım. –

+3

[3 Kuralı] 'na uymuyorsunuz (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – PaulMcKenzie

+4

Oh, bu kolay, sadece 'std :: string' kullan. Biliyorsun, C++. C. –

cevap

3

Sean Cline'ın bu yorumu neden bir yanıt olarak göndermediğinden emin değilim, ancak Sean doğru.

name_g elemanları verilir ve daha sonra name_[g] sıfıra ayarlanır, ancak name_[g] dizinin sonunun biridir. Dizinin sonunu geçmemek için name_ = new char[g+1]; veya name_[g-1] = 0; kullanın.

Ayrıca olarak çeşitli yorumlarda işaret, dinamik bellek ayırır bir sınıf var her sefer, kopya kurucu, atama operatörü ve yıkıcı tanımlayan emin olun. Birini özlüyorsanız, varsayılan uygulama sizin için baş ağrılarına neden olabilecek sığ kopyayı gerçekleştirecektir. işaretçi bunun yerine işaret veri kopyalandığında

bir basit bir kopyasını olup. Sizin durumunuzda, eğer bu sınıfın bir nesnesi kopyalanmışsa veya atanmışsa, öbek üzerinde aynı verilere işaret eden iki nesne ile sonuçlanırsınız ve her ikisi de kendi yıkıcılarını çalıştırdıklarında onu silmeye çalışırlar. `Yığın bozarak, tahsis edilen dizinin sonundaki yazar;

bu işlevleri hakkında daha fazla bilgi için, Rule of Three