Ralat: 'GDB Tidak Dapat Mengakses Memori di Alamat' dalam C++

Ralat Gdb Tidak Dapat Mengakses Memori Di Alamat Dalam C



Penyahpepijatan ialah bahagian penting dalam proses apabila membangunkan aplikasi dalam C++ atau mana-mana bahasa pengaturcaraan lain. Mencipta aplikasi dalam C++ bukanlah mudah; ia melibatkan kemahiran struktur data yang baik, kemahiran membetulkan pepijat dan mengurus alat penyahpepijatan. GDB, GNU Debugger, ialah alat cekap yang membantu pembangun mengenal pasti dan menyelesaikan ralat dalam kod mereka. GDB ialah alat yang mudah dan berguna yang membantu pembangun mencari dan membetulkan pepijat kod.

Walau bagaimanapun, semasa menggunakan GDB, anda mungkin menghadapi ralat 'ralat: GDB tidak boleh mengakses memori pada alamat'. Ralat ini boleh mengelirukan dan menyukarkan untuk meneruskan penyahpepijatan. Artikel ini memberi tumpuan kepada mengenal pasti sebab ralat ini berlaku dan melihat beberapa contoh kod yang membantu kami memahami cara menyelesaikan ralat ini.

Contoh 1:

Mari kita lihat contoh kod pertama kami yang, apabila dilaksanakan, memberikan ralat 'GDB tidak boleh mengakses memori pada alamat'. Pertama, kita melihat kod. Kemudian, kita akan melihat penjelasan baris demi baris mengenainya.







#include
menggunakan ruang nama std ;
int utama ( batal ) {
int * hlm ;
cout << * hlm ;
}

Program ini bermula dengan pengisytiharan arahan prapemproses '#include ' dan menggunakan 'std namespace' yang penting untuk disertakan dalam program untuk menggunakan fungsi input dan output standard. Selepas itu, titik masuk utama datang iaitu 'int main(void);'. Baris ini mengisytiharkan titik permulaan program.



Dalam fungsi utama, pembolehubah penunjuk “*p” diisytiharkan. Di sini, pembolehubah 'p' tidak dimulakan. Oleh itu, ia tidak menunjuk kepada mana-mana lokasi memori khusus yang dikhaskan untuk integer. Baris ini menyebabkan ralat yang akan kami selesaikan kemudian. Dalam baris seterusnya, kami cuba mencetak nilai pembolehubah '*p' menggunakan pernyataan 'cout'.



Oleh kerana pembolehubah 'p' ialah penunjuk jenis integer, asterisk '*' digunakan untuk membatalkan rujukannya. Ini bermakna bahawa nilai berada di lokasi memori yang ditunjukkannya. Walau bagaimanapun, kerana penuding 'p' tidak dimulakan dan tidak menghala ke mana-mana lokasi yang khusus dan sah, penyahrujukan penuding akan mengakibatkan tingkah laku yang tidak ditentukan. Oleh itu, ia menghasilkan pelbagai jenis ralat bergantung kepada sistem dan pengkompil. Memandangkan kami menggunakan pengkompil GDB untuk nyahpepijat dan menjalankan program ini, penyahpepijat akan membuang ralat berikut. Ralat ditunjukkan dalam coretan output:





Seperti yang anda lihat dalam output, penyahpepijat tidak boleh mengakses memori. Program ini menolak rujukan penunjuk yang tidak dimulakan, sebab utama bagi tingkah laku yang tidak ditentukan ini. Sekarang, mari kita lihat bagaimana kita boleh menyelesaikan masalah ini. Kod yang betul diberikan dalam yang berikut. Sila lihat dan kami akan menerangkan cara kami membetulkan pepijat dalam kod:



#include
menggunakan ruang nama std ;
int utama ( batal ) {
int val = 5 ;
int * hlm = & val ;
cout << 'Nilainya ialah = ' << * hlm ;

}

Seperti yang anda lihat, kod tersebut diubah suai dengan memasukkan 'int val =5;' kenyataan. Baris ini mengisytiharkan pembolehubah integer bernama 'val' dan memulakannya dengan nilai '5'. Baris seterusnya, “int *p = &val;”, mengisytiharkan pembolehubah penunjuk “*p” dan dimulakan untuk menunjuk ke alamat pembolehubah “val”. Sebelum ini, penunjuk '*p' tidak menunjuk ke mana-mana alamat memori yang menyebabkan 'tidak boleh mengakses memori pada alamat 0x0'.

Untuk menyelesaikan isu ini, pembolehubah 'var' diisytiharkan, dimulakan dan diberikan kepada penuding '*p'. Sekarang, penunjuk '*p' menunjuk ke alamat pembolehubah 'val' kerana pengendali '&' mengambil alamat 'val' dan menetapkannya kepada 'p'. Sekali lagi, pernyataan 'cout' digunakan untuk mencetak nilai penunjuk '*p'. Lihat coretan output berikut untuk melihat nilai 'val' yang diakses oleh penuding '*p':

Seperti yang anda boleh perhatikan, ralat telah diselesaikan dan nilai '5' dimulakan sejak pembolehubah 'val' telah dicetak dengan memanggil penunjuk '*p' valribale.

Contoh 2:

Mari kita pertimbangkan contoh lain yang menerangkan cara untuk memenuhi ralat 'GDB tidak boleh mengakses memori pada alamat' dalam program kod C++. Kod diberikan dalam perkara berikut untuk rujukan anda. Sila lihat:

#include
int utama ( ) {
int * hlm = baru int [ lima belas ] ;
padam [ ] hlm ;
std :: cout << hlm [ 2 ] << std :: endl ;
kembali 0 ;
}

Salah satu senario paling biasa yang dihadapi oleh pembangun semasa pengaturcaraan dengan penunjuk ialah peruntukan memori yang salah atau tidak betul. GDB menghasilkan ralat apabila peruntukan memori dan deallocation yang salah berlaku dalam program C++.

Memandangkan contoh kod sebelumnya, penunjuk “*p” dimulakan dengan int baharu[15]. Pernyataan ini memperuntukkan tatasusunan 15 integer secara dinamik menggunakan operator baharu. Pembolehubah penunjuk '*p' menyimpan alamat memori tatasusunan.

Dalam pernyataan berikut, 'padam[] p;,' menyatakan bahawa memori telah diagihkan menggunakan perintah padam[]. Perintah padam[] memperuntukkan memori yang telah diperuntukkan sebelumnya bagi penuding “*p” yang bermaksud bahawa penggunaan sistem lain boleh memperuntukkan blok memori yang diperuntukkan sebelum ini semula. Apabila kami cuba mencetak nilai pembolehubah '*p' menggunakan pernyataan 'cout', kami akan mendapat ralat akses memori seperti yang dilihat dalam output berikut:

Perkara yang perlu diingat di sini ialah mesej ralat yang tepat mungkin berbeza sedikit bergantung pada versi dan sistem GDB anda. Tetapi 'ralat: GDB tidak boleh mengakses memori di lokasi' dan ralat yang diberikan dalam coretan sebelumnya adalah sama. Untuk menyelesaikan ralat ini, kami hanya mengalihkan perintah delete[] selepas pernyataan 'cout'. Lihat kod yang diubah suai dalam perkara berikut:

#include
int utama ( ) {
int * hlm = baru int [ lima belas ] ;
untuk ( int i = 0 ; i < lima belas ; ++ i ) {
hlm [ i ] = i * 2 - 5 + 8 ;
std :: cout << 'p[' << i << '] = ' << hlm [ i ] << std :: endl ;
}
padam [ ] hlm ;
kembali 0 ;
}

Di sini, anda boleh melihat bahawa kami memulakan tatasusunan dengan nilai yang dikira pada masa larian dan kami mencetak semua nilai gelung menggunakan gelung 'untuk'. Perkara yang paling penting untuk diperhatikan di sini ialah peralihan kenyataan delete[]; ia kini dipanggil selepas mendapat semua nilai tatasusunan yang telah mengalih keluar ralat akses memori. Lihat output akhir kod dalam perkara berikut:

Kesimpulan

Kesimpulannya, ralat 'ralat: GDB tidak boleh mengakses memori pada alamat' biasanya menunjukkan isu berkaitan memori dalam kod C++. Artikel ini meneroka beberapa senario biasa yang memulakan ralat ini untuk menerangkan masa dan cara ia boleh diselesaikan. Apabila ralat ini berlaku dalam kod, adalah penting untuk menyemaknya dengan teliti dengan memberi perhatian yang teliti kepada pembolehubah penunjuk, peruntukan memori, tatasusunan dan struktur.

Selain itu, ciri seperti titik putus yang disediakan oleh GDB boleh membantu dalam mengesan ralat semasa menyahpepijat atur cara. Ciri-ciri ini boleh membantu dalam menentukan lokasi sebenar ralat berkaitan memori. Dengan menangani isu ini secara proaktif, pembangun boleh meningkatkan kestabilan dan kebolehpercayaan aplikasi C++ mereka.