c errors undefined reference
ağ aygıtları ve osi katmanları
Bu Öğretici, Programcıların genellikle Tanımlanmamış Referans, Segmentasyon Hatası (çekirdek dökülmüş) ve Çözümlenmemiş Harici Sembol gibi C ++ 'da Karşılaştığı Kritik Hataların Ayrıntılarını Verir:
C ++ 'da sıklıkla karşılaştığımız, gerçekten de eşit derecede kritik olan en önemli hataları tartışacağız. Zaman zaman meydana gelen sistem ve anlamsal hatalar ve istisnalar dışında, programların çalışmasını etkileyen diğer kritik hataları da alıyoruz.
Bu hatalar çoğunlukla çalışma zamanında programın sonuna doğru ortaya çıkar. Bazen program doğru çıktı verir ve ardından hata oluşur.
=> Sıfırdan C ++ Öğrenmek İçin Burayı Ziyaret Edin.
Ne öğreneceksin:
Önemli C ++ Hataları
Bu eğiticide, herhangi bir C ++ programcısının bakış açısından kritik olan üç tür hatayı tartışacağız.
- Tanımlanmamış referans
- Segmentasyon hatası (çekirdek dökülmüş)
- Çözümlenmemiş harici sembol
Bu hataların her birinin olası nedenlerini ve bu hataları önlemek için bir programcı olarak alabileceğimiz önlemleri tartışacağız.
Hadi başlayalım!!
Tanımlanmamış referans
Programımızda nesne adına (sınıf, işlev, değişken vb.) Bir referansımız olduğunda ve bağlayıcı tüm bağlantılı nesne dosyalarında ve kitaplıklarda onu aramaya çalıştığında tanımını bulamadığında 'Tanımlanmamış Referans' hatası oluşur. .
Bu nedenle, bağlayıcı, bağlantılı bir nesnenin tanımını bulamadığında, 'tanımsız referans' hatası verir. Tanımdan da anlaşılacağı gibi, bu hata, bağlama işleminin sonraki aşamalarında ortaya çıkar. 'Tanımlanmamış referans' hatasına neden olan çeşitli nedenler vardır.
Bu nedenlerden bazılarını aşağıda tartışıyoruz:
# 1) Nesne İçin Tanım Sağlanmadı
Bu, 'tanımlanmamış referans' hatasına neden olmanın en basit nedenidir. Programcı basitçe nesneyi tanımlamayı unutmuştur.
Aşağıdaki C ++ programını düşünün. Burada sadece fonksiyonun prototipini belirledik ve sonra onu ana fonksiyonda kullandık.
#include int func1(); int main() { func1(); }
Çıktı:
Dolayısıyla bu programı derlediğimizde, 'func1 ()' için tanımsız başvuru 'yazan bağlayıcı hatası verilir.
Bu hatadan kurtulmak için func1 fonksiyonunun tanımını sağlayarak programı aşağıdaki gibi düzeltiriz. Şimdi program uygun çıktıyı veriyor.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Çıktı:
Selam Dünya!!
# 2) Kullanılan Nesnelerin Yanlış Tanımı (imzalar eşleşmiyor)
'Tanımlanmamış referans' hatasının bir başka nedeni de yanlış tanımları belirttiğimiz zamandır. Programımızda herhangi bir nesneyi kullanıyoruz ve tanımı farklı bir şey.
Aşağıdaki C ++ programını düşünün. Burada func1 () 'e bir çağrı yaptık. Prototipi int func1 () 'dir. Ancak tanımı, prototipiyle uyuşmuyor. Gördüğümüz gibi, fonksiyonun tanımı fonksiyona bir parametre içermektedir.
Böylece program derlendiğinde prototip ve işlev çağrısı uyuşması nedeniyle derleme başarılı olur. Ancak bağlayıcı işlev çağrısını tanımıyla ilişkilendirmeye çalışırken, sorunu bulur ve hatayı 'tanımsız referans' olarak yayınlar.
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Çıktı:
Bu nedenle, bu tür hataları önlemek için, programımızdaki tüm nesnelerin tanımlarının ve kullanımlarının eşleşip eşleşmediğini çapraz kontrol ederiz.
# 3) Düzgün Bağlanmayan Nesne Dosyaları
Bu sorun aynı zamanda “tanımlanmamış referans” hatasına da neden olabilir. Burada birden fazla kaynak dosyamız olabilir ve bunları bağımsız olarak derleyebiliriz. Bu yapıldığında, nesneler doğru bir şekilde bağlanmaz ve 'tanımsız referans' ile sonuçlanır.
Aşağıdaki iki C ++ programını düşünün. İlk dosyada, ikinci dosyada tanımlanan “print ()” fonksiyonunu kullanıyoruz. Bu dosyaları ayrı ayrı derlediğimizde, ilk dosya yazdırma fonksiyonu için “tanımsız referans” verirken, ikinci dosya ana fonksiyon için “tanımsız referans” verir.
int print(); int main() { print(); }
Çıktı:
int print() { return 42; }
Çıktı:
Bu hatayı çözmenin yolu, her iki dosyayı aynı anda derlemektir ( Örneğin, g ++ kullanarak).
Halihazırda tartışılan nedenlerin yanı sıra, aşağıdaki nedenlerle “tanımlanmamış referans” da ortaya çıkabilir.
# 4) Yanlış Proje Türü
Görsel stüdyo gibi C ++ IDE'lerde yanlış proje türleri belirlediğimizde ve projenin beklemediği şeyleri yapmaya çalıştığımızda “tanımsız referans” elde ediyoruz.
# 5) Kitaplık Yok
Bir programcı kütüphane yolunu doğru bir şekilde belirtmemişse veya belirtmeyi tamamen unutmuşsa, o zaman programın kütüphaneden kullandığı tüm referanslar için 'tanımsız referans' alırız.
# 6) Bağımlı Dosyalar Derlenmiyor
Bir programcı, projenin tüm bağımlılıklarını önceden derlediğimizden emin olmalıdır, böylece projeyi derlediğimizde, derleyici tüm bağımlılıkları bulur ve başarıyla derler. Bağımlılıklardan herhangi biri eksikse, derleyici 'tanımsız başvuru' verir.
Yukarıda tartışılan nedenlerin yanı sıra, 'tanımlanmamış referans' hatası birçok başka durumda ortaya çıkabilir. Ancak işin özü, programcının bazı şeyleri yanlış anladığı ve bu hatayı önlemek için düzeltilmesi gerektiğidir.
mac için en iyi ücretsiz dvd ripper
Segmentasyon Hatası (çekirdek boşaltılmış)
'Segmentasyon hatası (çekirdek döküldü)' hatası, bellek bozulmasını gösteren bir hatadır. Genellikle, dikkate alınan programa ait olmayan bir belleğe erişmeye çalıştığımızda ortaya çıkar.
Segmentasyon hatası hatasına neden olan nedenlerden bazıları şunlardır.
# 1) Sabit Dizeyi Değiştirme
Sabit bir dizge tanımladığımız aşağıdaki programı düşünün. Sonra bu sabit dizeyi değiştirmeye çalışıyoruz. Program çalıştırıldığında çıktıda gösterilen hatayı alıyoruz.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Çıktı:
# 2) Başvurudan Çıkarma İşaretçisi
Bir gösterici, referansını kaldırmadan önce geçerli bir bellek konumuna işaret etmelidir. Aşağıdaki programda, işaretçinin NULL'u gösterdiğini görüyoruz, bu da işaret ettiği bellek konumunun 0, yani geçersiz olduğu anlamına gelir.
Bu nedenle, bir sonraki satırda referansını kaldırdığımızda, aslında bilinmeyen hafıza konumuna erişmeye çalışıyoruz. Bu gerçekten bir bölümleme hatasıyla sonuçlanır.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Çıktı:
Segmentasyon hatası
Bir sonraki program benzer bir durumu göstermektedir. Bu programda da işaretçi geçerli veriyi göstermiyor. Başlatılmamış bir işaretçi NULL kadar iyidir ve dolayısıyla bilinmeyen bellek konumuna da işaret eder. Bu nedenle, onu kaldırmaya çalıştığımızda, bu bir segmentasyon hatasıyla sonuçlanır.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Çıktı:
Segmentasyon hatası
Bu tür hataları önlemek için, programdaki işaretçi değişkenlerimizin her zaman geçerli bellek konumlarını gösterdiğinden emin olmalıyız.
# 3) Yığın Taşması
Programımızda yinelemeli çağrılar olduğunda, yığındaki tüm belleği tüketirler ve yığının taşmasına neden olurlar. Bu gibi durumlarda, yığın belleğinin tükenmesi de bir tür bellek bozulması olduğu için bölümleme hatası alıyoruz.
Bir sayının faktöriyelini özyinelemeli olarak hesapladığımız aşağıdaki programı düşünün. Temel koşulumuzun sayının 0 olup olmadığını test ettiğini ve ardından 1 döndürdüğünü unutmayın. Bu program pozitif sayılar için mükemmel çalışır.
Ama aslında negatif bir sayıyı faktöryel bir işleve geçirdiğimizde ne olur? Negatif sayılar için temel koşul verilmediğinden, fonksiyon nerede duracağını bilemez ve dolayısıyla bir yığın taşmasına neden olur.
Bu, bölümleme hatası veren aşağıdaki çıktıda gösterilmiştir.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Çıktı:
en iyi ücretsiz e-posta nedir
Segmentasyon hatası (çekirdek dökülmüş)
Şimdi bu hatayı düzeltmek için temel koşulu biraz değiştiriyoruz ve ayrıca aşağıda gösterildiği gibi negatif sayıların durumunu da belirtiyoruz.
#include using namespace std; int factorial(int n) { // What about n <0? if(n <= 0) { return 1; } return factorial(n-1) * n; } int main() { cout<<'Factorial output:'< Çıktı:
Faktöriyel çıktı: 1
Şimdi segmentasyon arızasının halledildiğini ve programın iyi çalıştığını görüyoruz.
Çözümlenmemiş Harici Sembol
Çözülmemiş harici sembol, bağlama işlemi sırasında sembolü veya referansını bulamadığını gösteren bir bağlayıcı hatasıdır. Hata, 'tanımsız referans' a benzer ve birbirinin yerine verilir.
Aşağıda bu hatanın ortaya çıkabileceği iki örnek verdik.
# 1) Programda statik üye içeren bir yapı değişkenine başvurduğumuzda.
#include struct C { static int s; }; // int C::s; // Uncomment the following line to fix the error. int main() { C c; C::s = 1; }
Çıktı:

Yukarıdaki programda, C yapısı, dış programların erişemeyeceği statik üyelere sahiptir. Bu nedenle, ana işlevde ona bir değer atamaya çalıştığımızda, bağlayıcı sembolü bulamaz ve 'çözümlenmemiş harici simge' veya 'tanımlanmamış referans' ile sonuçlanabilir.
Bu hatayı düzeltmenin yolu, değişkeni kullanmadan önce main dışında '::' kullanarak açıkça kapsama almaktır.
# 2) Kaynak dosyada referans verilen harici değişkenlere sahip olduğumuzda ve bu harici değişkenleri tanımlayan dosyalara bağlanmadık.
Bu durum aşağıda gösterilmiştir:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Çıktı:

Genel olarak, bir 'çözümlenmemiş harici sembol' durumunda, işlev gibi herhangi bir nesne için derlenmiş kod, referans yaptığı bir sembolü bulamaz, belki de bu sembol nesne dosyalarında veya kitaplıkların herhangi birinde tanımlanmamış olabilir. bağlayıcıya belirtildi.
Sonuç
Bu öğreticide, C ++ 'da kritik olan ve program akışını etkileyebilecek ve hatta bir uygulama çökmesine neden olabilecek bazı önemli hataları tartıştık. Segmentasyon hatası, Çözümlenmemiş harici sembol ve Tanımsız referans hakkında her şeyi ayrıntılı olarak araştırdık.
Bu hatalar her an ortaya çıkabilse de tartıştığımız nedenlerden programımızı dikkatlice geliştirerek bunları kolayca önleyebileceğimizi biliyoruz.
=> Kolay C ++ Eğitim Serisini Okuyun.
Önerilen Kaynaklar