Fel: 'GDB kan inte komma åt minne på adress' i C++

Fel Gdb Kan Inte Komma At Minne Pa Adress I C



Felsökning är en viktig del av processen när man utvecklar applikationer i C++ eller något annat programmeringsspråk. Att skapa applikationer i C++ är inte lätt; det involverar goda kunskaper om datastruktur, färdigheter att fixa buggar och hantera felsökningsverktygen. GDB, GNU Debugger, är ett effektivt verktyg som hjälper utvecklarna att identifiera och lösa felen i sin kod. GDB är ett intressant enkelt och användbart verktyg som hjälper utvecklarna att hitta och fixa kodbuggarna.

Men när du använder GDB kan du stöta på felet 'fel: GDB kan inte komma åt minnet på adressen'. Det här felet kan vara förvirrande och gör det svårt att fortsätta felsöka. Den här artikeln fokuserar på att identifiera varför det här felet uppstår och titta på några exempel på kod som hjälper oss att förstå hur vi löser det här felet.

Exempel 1:

Låt oss se vårt första kodexempel som vid exekvering ger felet 'GDB kan inte komma åt minnet vid adress'. Först tittar vi på koden. Sedan kommer vi att se rad för rad förklaring av det.







#inkludera
använder sig av namnutrymme std ;
int huvud ( tomhet ) {
int * sid ;
cout << * sid ;
}

Programmet börjar med deklarationen av '#include ' förprocessordirektivet och använder 'namespace std' som är nödvändiga för att inkluderas i programmet för att använda standardinmatnings- och utdatafunktionerna. Efter det kommer huvudingången som är 'int main(void);'. Denna rad deklarerar programmets startpunkt.



Inom huvudfunktionen deklareras '*p'-pekarvariabeln. Här initieras inte 'p'-variabeln. Därför pekar den inte på någon specifik minnesplats som är reserverad för heltal. Den här raden orsakar ett fel som vi kommer att lösa senare. På nästa rad försöker vi skriva ut värdet på variabeln '*p' med hjälp av 'cout'-satsen.



Eftersom variabeln 'p' är en pekare av typen heltal, används asterisken '*' för att avreferensera den. Det betyder att värdet finns på den minnesplats det pekar på. Men eftersom 'p'-pekaren inte initierades och inte pekar på någon specifik och giltig plats, kommer det att hänvisa pekaren till ett odefinierat beteende. Därför resulterar det i att olika typer av fel genereras beroende på system och kompilator. Eftersom vi använder GDB-kompilatorn för att felsöka och köra detta program, kommer debuggern att ge följande fel. Felet visas i utdatautdraget:





Som du kan se i utgången kan felsökaren inte komma åt minnet. Detta program refererar till en oinitierad pekare, huvudorsaken till detta odefinierade beteende. Låt oss nu se hur vi kan lösa detta problem. Rätt kod ges i det följande. Ta en titt på det så kommer vi att förklara hur vi fixar buggen i koden:



#inkludera
använder sig av namnutrymme std ;
int huvud ( tomhet ) {
int val = 5 ;
int * sid = & val ;
cout << 'Värdet är = ' << * sid ;

}

Som du kan se modifieras koden genom att inkludera 'int val =5;' påstående. Den här raden deklarerar en heltalsvariabel med namnet 'val' och initierar den med värdet '5'. Nästa rad, 'int *p = &val;', deklarerar en '*p'-pekarvariabel och initieras för att peka på adressen för variabeln 'val'. Tidigare pekade '*p'-pekaren inte på någon minnesadress som orsakade 'kan inte komma åt minnet vid adress 0x0'.

För att lösa detta problem deklareras variabeln 'var', initieras och tilldelas '*p'-pekaren. Nu pekar '*p'-pekaren på adressen till variabeln 'val' eftersom '&'-operatorn tar adressen till 'val' och tilldelar den till 'p'. Återigen används 'cout'-satsen för att skriva ut värdet på '*p'-pekaren. Se följande utdatautdrag för att se värdet på 'val' som nås av '*p'-pekaren:

Som du kan se har felet lösts och värdet på '5' initieras eftersom variabeln 'val' har skrivits ut genom att anropa '*p'-pekaren valribale.

Exempel 2:

Låt oss överväga ett annat exempel som förklarar hur man tillgodoser felet 'GDB kan inte komma åt minne på adress' i C++-kodprogrammet. Koden ges i det följande för din referens. Ta en titt:

#include
int huvud ( ) {
int * sid = ny int [ femton ] ;
radera [ ] sid ;
std :: cout << sid [ 2 ] << std :: endl ;
lämna tillbaka 0 ;
}

Ett av de vanligaste scenarierna som utvecklarna stöter på när de programmerar med pekare är felaktig eller felaktig minnesallokering. GDB resulterar i felet när en felaktig minnesallokering och -deallokering inträffar i ett C++-program.

Med tanke på föregående kodexempel initialiseras en '*p'-pekare med en ny int[15]. Denna sats allokerar dynamiskt en array med 15 heltal med den nya operatorn. Pekarvariabeln '*p' lagrar minnesadressen för arrayen.

I följande uttalande anger 'delete[] p;,' att minnet har avallokerats med kommandot delete[]. Kommandot delete[] avallokerar det tidigare allokerade minnet för '*p'-pekaren, vilket innebär att det andra systemet som använder kan allokera det tidigare allokerade minnesblocket igen. När vi försöker skriva ut värdet på variabeln '*p' med hjälp av 'cout'-satsen, kommer vi att få minnesåtkomstfelet som visas i följande utdata:

Det du bör tänka på här är att det exakta felmeddelandet kan skilja sig något beroende på din GDB-version och ditt system. Men 'felet: GDB kan inte komma åt minnet på platsen' och det givna felet i föregående kodavsnitt är desamma. För att lösa detta fel flyttar vi helt enkelt kommandot delete[] efter 'cout'-satsen. Se den ändrade koden i följande:

#include
int huvud ( ) {
int * sid = ny int [ femton ] ;
för ( int i = 0 ; i < femton ; ++ i ) {
sid [ i ] = i * 2 - 5 + 8 ;
std :: cout << 'p[' << i << '] = ' << sid [ i ] << std :: endl ;
}
radera [ ] sid ;
lämna tillbaka 0 ;
}

Här kan du se att vi initierade arrayen med värden som beräknas vid körning, och vi skriver ut alla värden för slingan med hjälp av 'for'-loopen. Det viktigaste att notera här är förskjutningen av delete[]-satsen; det anropas nu efter att ha fått alla värden för den array som har tagit bort minnesåtkomstfelet. Se den slutliga utmatningen av koden i följande:

Slutsats

Sammanfattningsvis indikerar felet 'fel: GDB kan inte komma åt minnet på adressen' vanligtvis minnesrelaterade problem i C++-koden. Den här artikeln utforskade några vanliga scenarier som initierar det här felet för att förklara när och hur det kan lösas. När det här felet inträffar i koden är det viktigt att noggrant granska det genom att noggrant vara uppmärksam på pekarvariablerna, minnesallokeringarna, arrayerna och strukturerna.

Dessutom kan funktioner som brytpunkter som tillhandahålls av GDB hjälpa till att lokalisera felet under felsökning av programmet. Dessa funktioner kan hjälpa till att fastställa den exakta platsen för minnesrelaterade fel. Genom att ta itu med dessa problem proaktivt kan utvecklarna förbättra stabiliteten och tillförlitligheten hos sina C++-applikationer.