Грешка: „ГДБ не може да приступи меморији на адреси“ у Ц++

Greska Gdb Ne Moze Da Pristupi Memoriji Na Adresi U C



Отклањање грешака је суштински део процеса када се развијају апликације на Ц++ или било ком другом програмском језику. Креирање апликација у Ц++ није лако; укључује добре вештине структуре података, вештине исправљања грешака и управљање алатима за отклањање грешака. ГДБ, ГНУ Дебуггер, је ефикасан алат који помаже програмерима да идентификују и реше грешке у свом коду. ГДБ је занимљиво једноставан и користан алат који помаже програмерима да пронађу и поправе грешке кода.

Међутим, док користите ГДБ, можда ћете наићи на грешку „грешка: ГДБ не може приступити меморији на адреси“. Ова грешка може бити збуњујућа и отежава наставак отклањања грешака. Овај чланак је фокусиран на идентификацију зашто се ова грешка јавља и на неке примере кода који нам помажу да разумемо како да решимо ову грешку.

Пример 1:

Хајде да видимо наш први пример кода који, након извршења, даје грешку „ГДБ не може приступити меморији на адреси“. Прво, погледамо код. Затим ћемо видети његово објашњење ред по ред.







#инцлуде<иостреам>
Користећи именског простора стд ;
инт главни ( празнина ) {
инт * стр ;
цоут << * стр ;
}

Програм почиње декларацијом препроцесорске директиве „#инцлуде <стдио.х>” и коришћењем „простора имена стд” који су неопходни да би били укључени у програм за коришћење стандардних улазних и излазних функција. Након тога долази главна улазна тачка која је „инт маин(воид);“. Ова линија декларише почетну тачку програма.



Унутар главне функције, променљива показивача „*п“ је декларисана. Овде променљива „п“ није иницијализована. Дакле, не указује ни на једну специфичну меморијску локацију која је резервисана за цео број. Ова линија изазива грешку коју ћемо касније решити. У следећем реду покушавамо да одштампамо вредност променљиве „*п“ користећи наредбу „цоут“.



Пошто је променљива „п“ показивач типа целог броја, звездица „*“ се користи за њено дереференцирање. То значи да је вредност на меморијској локацији на коју указује. Међутим, пошто „п” показивач није иницијализован и не указује на било коју специфичну и важећу локацију, дереференцирање показивача ће довести до недефинисаног понашања. Дакле, то доводи до генерисања различитих врста грешака у зависности од система и компајлера. Пошто користимо ГДБ компајлер за отклањање грешака и покретање овог програма, програм за отклањање грешака ће избацити следећу грешку. Грешка је приказана у излазном исечку:





Као што можете видети у излазу, дебагер не може да приступи меморији. Овај програм дереференцира неиницијализовани показивач, главни разлог за ово недефинисано понашање. Сада, да видимо како можемо да решимо овај проблем. Тачан код је дат у наставку. Погледајте то и објаснићемо како поправљамо грешку у коду:



#инцлуде<иостреам>
Користећи именског простора стд ;
инт главни ( празнина ) {
инт вал = 5 ;
инт * стр = & вал ;
цоут << 'Вредност је = ' << * стр ;

}

Као што видите, код се мења укључивањем „инт вал =5;“ изјава. Ова линија декларише целобројну променљиву под називом „вал“ и иницијализује је вредношћу „5“. Следећи ред, „инт *п = &вал;“, декларише променљиву показивача „*п“ и иницијализује се да указује на адресу променљиве „вал“. Раније, показивач „*п“ није показивао ни на једну меморијску адресу што је изазвало „немогуће приступити меморији на адреси 0к0“.

Да би се решио овај проблем, променљива „вар“ је декларисана, иницијализована и додељена показивачу „*п“. Сада, показивач „*п“ показује на адресу променљиве „вал“ док оператор „&“ узима адресу „вал“ и додељује је „п“. Опет, наредба „цоут“ се користи за штампање вредности показивача „*п“. Погледајте следећи излазни исечак да бисте видели вредност „вал“ којој се приступа помоћу показивача „*п“:

Као што можете приметити, грешка је решена и вредност „5“ је иницијализована пошто је променљива „вал“ одштампана позивањем показивача „*п“ валрибале.

Пример 2:

Хајде да размотримо још један пример који објашњава како да се позабавимо грешком „ГДБ не може приступити меморији на адреси“ у програму Ц++ кода. Код је дат у наставку за вашу референцу. Погледај:

#инцлуде <иостреам>
инт главни ( ) {
инт * стр = Нова инт [ петнаест ] ;
избрисати [ ] стр ;
стд :: цоут << стр [ 2 ] << стд :: ендл ;
повратак 0 ;
}

Један од најчешћих сценарија са којима се програмери сусрећу док програмирају помоћу показивача је нетачна или неправилна алокација меморије. ГДБ резултира грешком кад год дође до погрешне алокације и ослобађања меморије у Ц++ програму.

Узимајући у обзир претходни пример кода, показивач “*п” се иницијализује са новим инт[15]. Ова изјава динамички додељује низ од 15 целих бројева користећи оператор нев. Променљива показивача „*п“ чува меморијску адресу низа.

У следећој изјави, „делете[] п;,” наводи да је меморија ослобођена коришћењем команде делете[]. Команда делете[] ослобађа претходно додељену меморију показивача „*п“, што значи да други систем који користи може поново да додели претходно додељени меморијски блок. Када покушамо да одштампамо вредност променљиве „*п“ користећи наредбу „цоут“, добићемо грешку приступа меморији као што се види у следећем излазу:

Оно што овде треба имати на уму је да се тачна порука о грешци може мало разликовати у зависности од ваше ГДБ верзије и система. Али „грешка: ГДБ не може да приступи меморији на локацији“ и дата грешка у претходном исечку су исте. Да бисмо решили ову грешку, једноставно померимо команду делете[] после изјаве „цоут“. Погледајте измењени код у наставку:

#инцлуде <иостреам>
инт главни ( ) {
инт * стр = Нова инт [ петнаест ] ;
за ( инт и = 0 ; и < петнаест ; ++ и ) {
стр [ и ] = и * 2 - 5 + 8 ;
стд :: цоут << 'п[' << и << '] = ' << стр [ и ] << стд :: ендл ;
}
избрисати [ ] стр ;
повратак 0 ;
}

Овде можете видети да смо иницијализовали низ вредностима које су израчунате у време извођења и да штампамо све вредности петље користећи петљу „фор“. Најважнија ствар коју треба приметити је померање наредбе делете[]; сада се позива након добијања свих вредности низа који је уклонио грешку приступа меморији. Погледајте коначни излаз кода у следећем:

Закључак

У закључку, грешка „грешка: ГДБ не може приступити меморији на адреси“ обично указује на проблеме везане за меморију у Ц++ коду. Овај чланак је истражио неке уобичајене сценарије који покрећу ову грешку да би се објаснило када и како се може решити. Када се ова грешка појави у коду, неопходно је пажљиво је прегледати обраћајући велику пажњу на променљиве показивача, алокације меморије, низове и структуре.

Штавише, функције попут тачака прекида које обезбеђује ГДБ могу помоћи у лоцирању грешке током отклањања грешака у програму. Ове функције могу помоћи у одређивању тачне локације грешака у вези са меморијом. Проактивним решавањем ових проблема, програмери могу побољшати стабилност и поузданост својих Ц++ апликација.