Virhe: 'GDB ei voi käyttää muistia osoitteessa' C++:ssa

Virhe Gdb Ei Voi Kayttaa Muistia Osoitteessa C Ssa



Vianetsintä on olennainen osa prosessia kehitettäessä sovelluksia C++:lla tai millä tahansa muulla ohjelmointikielellä. Sovellusten luominen C++:ssa ei ole helppoa; se sisältää hyvät tietorakenteen taidot, virheenkorjaustaidot ja virheenkorjaustyökalujen hallinnan. GDB, GNU Debugger, on tehokas työkalu, joka auttaa kehittäjiä tunnistamaan ja ratkaisemaan koodinsa virheet. GDB on mielenkiintoisen yksinkertainen ja hyödyllinen työkalu, joka auttaa kehittäjiä löytämään ja korjaamaan koodivirheet.

GDB:tä käytettäessä saatat kuitenkin kohdata virheilmoituksen 'virhe: GDB ei voi käyttää muistia osoitteessa'. Tämä virhe voi olla hämmentävä ja vaikeuttaa virheenkorjauksen jatkamista. Tämä artikkeli keskittyy tunnistamaan tämän virheen syy ja tarkastelemaan joitakin esimerkkejä koodista, jotka auttavat meitä ymmärtämään, kuinka tämä virhe ratkaistaan.

Esimerkki 1:

Katsotaanpa ensimmäistä koodiesimerkkiämme, joka suorittaa suorituksen yhteydessä virheen 'GDB ei voi käyttää muistia osoitteessa'. Ensin katsomme koodia. Sitten näemme sen rivi riviltä selityksen.







#include
käyttämällä nimiavaruus std ;
int pää ( mitätön ) {
int * s ;
cout << * s ;
}

Ohjelma alkaa esiprosessoridirektiivin '#include ' julistuksella ja 'namespace std':llä, jotka ovat välttämättömiä sisällytettäväksi ohjelmaan, jotta voidaan käyttää vakiosyöttö- ja lähtötoimintoja. Sen jälkeen tulee päätulopiste, joka on 'int main(void);'. Tämä rivi ilmoittaa ohjelman aloituspisteen.



Pääfunktion sisällä ilmoitetaan osoitinmuuttuja '*p'. Tässä 'p'-muuttujaa ei ole alustettu. Siksi se ei osoita mihinkään tiettyyn muistipaikkaan, joka on varattu kokonaisluvulle. Tämä rivi aiheuttaa virheen, jonka korjaamme myöhemmin. Seuraavalla rivillä yritämme tulostaa '*p'-muuttujan arvon 'cout'-käskyn avulla.



Koska 'p'-muuttuja on kokonaislukutyyppinen osoitin, sen viittauksen poistamiseen käytetään tähteä '*'. Tämä tarkoittaa, että arvo on siinä muistipaikassa, johon se osoittaa. Koska 'p'-osoitinta ei kuitenkaan alustettu eikä se osoita mihinkään tiettyyn ja kelvolliseen sijaintiin, osoittimen viittauksen poistaminen johtaa määrittelemättömään toimintaan. Tästä syystä se tuottaa erilaisia ​​​​virheitä järjestelmästä ja kääntäjästä riippuen. Koska käytämme GDB-kääntäjää tämän ohjelman virheenkorjaukseen ja suorittamiseen, debuggeri antaa seuraavan virheen. Virhe näkyy tulostepätkässä:





Kuten tulosteessa näkyy, debuggeri ei voi käyttää muistia. Tämä ohjelma poistaa viittaukset alustamattomaan osoittimeen, mikä on tärkein syy tähän määrittelemättömään toimintaan. Katsotaan nyt, kuinka voimme ratkaista tämän ongelman. Oikea koodi on annettu seuraavassa. Katso sitä ja selitämme, kuinka korjaamme koodin virheen:



#include
käyttämällä nimiavaruus std ;
int pää ( mitätön ) {
int val = 5 ;
int * s = & val ;
cout << 'Arvo on =' << * s ;

}

Kuten näet, koodia muutetaan lisäämällä 'int val =5;' lausunto. Tämä rivi ilmoittaa kokonaislukumuuttujan nimeltä 'val' ja alustaa sen arvolla '5'. Seuraava rivi 'int *p = &val;' ilmoittaa '*p'-osoitinmuuttujan ja alustetaan osoittamaan 'val'-muuttujan osoitteeseen. Aikaisemmin '*p'-osoitin ei osoittanut mihinkään muistiosoitteeseen, mikä aiheutti 'ei voi käyttää muistia osoitteessa 0x0'.

Tämän ongelman ratkaisemiseksi 'var'-muuttuja ilmoitetaan, alustetaan ja määritetään '*p'-osoittimelle. Nyt '*p'-osoitin osoittaa 'val'-muuttujan osoitteeseen, koska '&'-operaattori ottaa 'val'-osoitteen ja määrittää sen 'p:ksi'. Jälleen 'cout'-käskyä käytetään '*p'-osoittimen arvon tulostamiseen. Katso seuraava tuloskoodinpätkä nähdäksesi 'val'-arvon, johon '*p'-osoitin pääsee:

Kuten huomaat, virhe on korjattu ja arvo '5' alustetaan, koska 'val'-muuttuja on tulostettu kutsumalla '*p'-osoitin valribale.

Esimerkki 2:

Tarkastellaan toista esimerkkiä, joka selittää, kuinka C++-koodiohjelman virhe 'GDB ei voi käyttää muistia osoitteessa' huomioida. Koodi on annettu seuraavassa viitteeksi. Katso:

#include
int pää ( ) {
int * s = Uusi int [ viisitoista ] ;
poistaa [ ] s ;
std :: cout << s [ 2 ] << std :: endl ;
palata 0 ;
}

Yksi yleisimmistä skenaarioista, joita kehittäjät kohtaavat ohjelmoiessaan osoittimilla, on virheellinen tai virheellinen muistin varaus. GDB aiheuttaa virheen aina, kun C++-ohjelmassa tapahtuu virheellinen muistin varaus ja purkaminen.

Edellisessä koodiesimerkissä '*p'-osoitin alustetaan uudella int:llä[15]. Tämä lauseke varaa dynaamisesti 15 kokonaisluvun taulukon käyttämällä uutta operaattoria. Osoitinmuuttuja '*p' tallentaa taulukon muistiosoitteen.

Seuraavassa lauseessa 'delete[] p;' ilmoittaa, että muisti on vapautettu käyttämällä delete[]-komentoa. Komento delete[] vapauttaa '*p'-osoittimen aiemmin varatun muistin, mikä tarkoittaa, että muut järjestelmän käyttäjät voivat varata aiemmin varatun muistilohkon uudelleen. Kun yritämme tulostaa '*p'-muuttujan arvon 'cout'-käskyllä, saamme muistin käyttövirheen, joka näkyy seuraavassa tulosteessa:

Tässä on pidettävä mielessä, että tarkka virheilmoitus saattaa vaihdella hieman GDB-versiosi ja järjestelmäsi mukaan. Mutta 'virhe: GDB ei voi käyttää muistia sijainnissa' ja annettu virhe edellisessä katkelmassa ovat samat. Tämän virheen ratkaisemiseksi siirrämme delete[]-komennon 'cout'-käskyn jälkeen. Katso muokattu koodi seuraavasta:

#include
int pää ( ) {
int * s = Uusi int [ viisitoista ] ;
varten ( int i = 0 ; i < viisitoista ; ++ i ) {
s [ i ] = i * 2 - 5 + 8 ;
std :: cout << 'p[' << i << '] = ' << s [ i ] << std :: endl ;
}
poistaa [ ] s ;
palata 0 ;
}

Täällä voit nähdä, että alustimme taulukon arvoilla, jotka lasketaan ajon aikana, ja tulostamme kaikki silmukan arvot käyttämällä 'for'-silmukkaa. Tärkein huomioitava asia on delete[]-lauseen siirtyminen; sitä kutsutaan nyt saatuaan kaikki sen taulukon arvot, joka on poistanut muistin käyttövirheen. Katso koodin lopullinen tulos seuraavasta:

Johtopäätös

Yhteenvetona voidaan todeta, että 'virhe: GDB ei voi käyttää muistia osoitteessa' -virhe osoittaa yleensä muistiin liittyviä ongelmia C++-koodissa. Tässä artikkelissa tarkasteltiin joitain yleisiä skenaarioita, jotka aiheuttavat tämän virheen, jotta selitetään, milloin ja miten se voidaan ratkaista. Kun tämä virhe ilmenee koodissa, on tärkeää tarkistaa se huolellisesti kiinnittämällä erityistä huomiota osoitinmuuttujiin, muistin varauksiin, taulukoihin ja rakenteisiin.

Lisäksi GDB:n tarjoamat ominaisuudet, kuten keskeytyskohdat, voivat auttaa löytämään virheen ohjelman virheenkorjauksen aikana. Nämä ominaisuudet voivat auttaa määrittämään muistiin liittyvien virheiden tarkan sijainnin. Käsittelemällä näitä ongelmia ennakoivasti kehittäjät voivat parantaa C++ -sovellustensa vakautta ja luotettavuutta.