Hata: C++'da 'GDB Adresteki Belleğe Erişemiyor'

Hata C Da Gdb Adresteki Bellege Erisemiyor



Hata ayıklama, C++ veya başka herhangi bir programlama dilinde uygulama geliştirirken sürecin önemli bir parçasıdır. C++'da uygulama oluşturmak kolay değildir; iyi veri yapısı becerilerini, hata düzeltme becerilerini ve hata ayıklama araçlarını yönetmeyi içerir. GDB, GNU Hata Ayıklayıcı, geliştiricilerin kodlarındaki hataları tanımlamasına ve çözmesine yardımcı olan etkili bir araçtır. GDB, geliştiricilerin kod hatalarını bulmasına ve düzeltmesine yardımcı olan ilginç derecede basit ve kullanışlı bir araçtır.

Ancak GDB kullanırken “hata: GDB adresteki belleğe erişemiyor” hatasıyla karşılaşabilirsiniz. Bu hata kafa karıştırıcı olabilir ve hata ayıklamaya devam etmeyi zorlaştırır. Bu makale, bu hatanın neden oluştuğunu belirlemeye ve bu hatanın nasıl çözüleceğini anlamamıza yardımcı olacak bazı kod örneklerine bakmaya odaklanmıştır.

Örnek 1:

Çalıştırıldığında “GDB adresteki belleğe erişemiyor” hatası veren ilk kod örneğimizi görelim. Öncelikle koda bakıyoruz. Daha sonra bunun satır satır açıklamasını göreceğiz.







#include
kullanarak ad alanı std ;
int ana ( geçersiz ) {
int * P ;
cout << * P ;
}

Program, “#include ” önişlemci direktifinin bildirilmesi ve standart giriş ve çıkış işlevlerinin kullanılması için programda bulunması gereken “namespace std”nin kullanılmasıyla başlar. Bundan sonra “int main(void);” olan ana giriş noktası gelir. Bu satır programın başlangıç ​​noktasını belirtir.



Ana fonksiyon içerisinde “*p” işaretçi değişkeni bildirilir. Burada “p” değişkeni başlatılmadı. Bu nedenle, tamsayı için ayrılmış herhangi bir spesifik hafıza konumuna işaret etmez. Bu satır daha sonra çözeceğimiz bir hataya neden oluyor. Bir sonraki satırda “cout” ifadesini kullanarak “*p” değişkeninin değerini yazdırmaya çalışıyoruz.



“p” değişkeni tamsayı türünde bir işaretçi olduğundan, referansı kaldırmak için “*” yıldız işareti kullanılır. Bu, değerin işaret ettiği bellek konumunda olduğu anlamına gelir. Ancak 'p' işaretçisi başlatılmadığından ve belirli ve geçerli bir konuma işaret etmediğinden işaretçinin referansının kaldırılması tanımsız davranışla sonuçlanacaktır. Dolayısıyla sisteme ve derleyiciye bağlı olarak çeşitli türde hataların üretilmesine neden olur. Bu programın hatalarını ayıklamak ve çalıştırmak için GDB derleyicisini kullandığımız için hata ayıklayıcı aşağıdaki hatayı atacaktır. Hata çıktı snippet'inde gösterilir:





Çıktıda görebileceğiniz gibi hata ayıklayıcı belleğe erişemiyor. Bu program, bu tanımsız davranışın ana nedeni olan başlatılmamış bir işaretçinin referansını kaldırır. Şimdi bu sorunu nasıl çözebileceğimize bakalım. Doğru kod aşağıda verilmiştir. Bir göz atın ve koddaki hatayı nasıl düzelteceğimizi açıklayacağız:



#include
kullanarak ad alanı std ;
int ana ( geçersiz ) {
int val = 5 ;
int * P = & val ;
cout << 'Değer =' << * P ;

}

Gördüğünüz gibi kod “int val =5;” eklenerek değiştiriliyor. ifade. Bu satır “val” adında bir tamsayı değişkeni bildirir ve onu “5” değeriyle başlatır. Sonraki satır olan 'int *p = &val;', bir '*p' işaretçi değişkeni bildirir ve 'val' değişkeninin adresini işaret edecek şekilde başlatılır. Daha önce “*p” işaretçisi herhangi bir bellek adresini göstermiyordu ve bu da “0x0 adresindeki belleğe erişilemiyor” hatasına neden oluyordu.

Bu sorunu çözmek için “var” değişkeni bildirilir, başlatılır ve “*p” işaretçisine atanır. Artık “*p” işaretçisi “val” değişkeninin adresini işaret ederken, “&” operatörü “val”in adresini alıp “p”ye atamaktadır. Yine “*p” işaretçisinin değerini yazdırmak için “cout” ifadesi kullanılır. “*p” işaretçisi tarafından erişilen “val” değerini görmek için aşağıdaki çıktı parçacığına bakın:

Gördüğünüz gibi “*p” işaretçisi varribale çağrılarak “val” değişkeni yazdırıldığı için hata çözülmüş ve “5” değeri başlatılmıştır.

Örnek 2:

C++ kod programında “GDB adresteki belleğe erişemiyor” hatasının nasıl giderileceğini açıklayan başka bir örneği ele alalım. Kod aşağıda referans olarak verilmiştir. Bir göz atın:

#include
int ana ( ) {
int * P = yeni int [ on beş ] ;
silmek [ ] P ;
std :: cout << P [ 2 ] << std :: sonunda ;
geri dönmek 0 ;
}

Geliştiricilerin işaretçilerle programlama yaparken karşılaştığı en yaygın senaryolardan biri yanlış veya hatalı bellek tahsisidir. Bir C++ programında yanlış bellek tahsisi ve serbest bırakma meydana geldiğinde GDB hataya neden olur.

Önceki kod örneği dikkate alındığında, “*p” işaretçisi yeni bir int[15] ile başlatılır. Bu ifade, new operatörünü kullanarak dinamik olarak 15 tam sayıdan oluşan bir diziyi tahsis eder. “*p” işaretçi değişkeni dizinin bellek adresini saklar.

Aşağıdaki ifadede “delete[] p;”, delete[] komutu kullanılarak belleğin serbest bırakıldığını belirtmektedir. Sil[] komutu, “*p” işaretçisinin daha önce tahsis edilen hafızasını serbest bırakır; bu, diğer sistemin kullandığı, daha önce tahsis edilen hafıza bloğunu tekrar tahsis edebileceği anlamına gelir. “*p” değişkeninin değerini “cout” ifadesini kullanarak yazdırmaya çalıştığımızda aşağıdaki çıktıda görüldüğü gibi hafıza erişim hatası alacağız:

Burada akılda tutulması gereken şey, tam hata mesajının GDB sürümünüze ve sisteminize bağlı olarak biraz farklılık gösterebileceğidir. Ancak “hata: GDB konumdaki belleğe erişemiyor” ve önceki kod parçasında verilen hata aynı. Bu hatayı çözmek için delete[] komutunu “cout” ifadesinin sonrasına kaydırmamız yeterli. Aşağıdaki değiştirilen koda bakın:

#include
int ana ( ) {
int * P = yeni int [ on beş ] ;
için ( int Ben = 0 ; Ben < on beş ; ++ Ben ) {
P [ Ben ] = Ben * 2 - 5 + 8 ;
std :: cout << 'P[' << Ben << '] = ' << P [ Ben ] << std :: sonunda ;
}
silmek [ ] P ;
geri dönmek 0 ;
}

Burada diziyi çalışma zamanında hesaplanan değerlerle başlattığımızı ve döngünün tüm değerlerini “for” döngüsünü kullanarak yazdırdığımızı görebilirsiniz. Burada dikkat edilmesi gereken en önemli husus, delete[] ifadesinin kaydırılmasıdır; artık belleğe erişim hatasını ortadan kaldıran dizinin tüm değerleri alındıktan sonra çağrılır. Aşağıdaki kodun son çıktısına bakın:

Çözüm

Sonuç olarak, 'hata: GDB adresteki belleğe erişemiyor' hatası genellikle C++ kodunda bellekle ilgili sorunları gösterir. Bu makalede, bu hatayı başlatan bazı yaygın senaryolar incelenerek sorunun ne zaman ve nasıl çözülebileceği açıklanmaktadır. Kodda bu hata oluştuğunda işaretçi değişkenlerine, bellek ayırmalarına, dizilere ve yapılara çok dikkat ederek hatanın dikkatlice gözden geçirilmesi önemlidir.

Ayrıca, GDB tarafından sağlanan kesme noktaları gibi özellikler, programda hata ayıklama sırasında hatanın bulunmasına yardımcı olabilir. Bu özellikler, bellekle ilgili hataların tam yerinin belirlenmesine yardımcı olabilir. Geliştiriciler bu sorunları proaktif bir şekilde ele alarak C++ uygulamalarının kararlılığını ve güvenilirliğini artırabilirler.