Въпрос:
Защо продължавам да получавам грешки при сегментиране, след като промених начина, по който декларирах и използвах моите указатели към обекти?
Според мен те изглеждат случайни, но съм сигурен, че има причина, обясняваща този хаос.
Брифинг:
Работя върху игра, подобна на Rogue, много подобна на NetHack, от няколко месеца и стигнах до друга точка, в която бях заседнал с дни. Подземието се показва и Играчът може да се движи наоколо с помощта на w,a,s,d. Когато влезете в контакт с същество, вие започвате да го атакувате. Имах това да работи до момента, в който Creature ‹= 0. Проблемът ми беше, че не можех да накарам показалеца на това създание да се върне към празно **Creature/NULL. Казаха ми, че това е свързано с начина, по който декларирах указателите в main.cpp, така че опитах няколко предложения и сега постоянно получавам seg faults. По някаква причина не мога да мръдна дори веднъж, след като играя през повечето време. Когато мога да се движа, съм добър, докато HP на Creature ‹= 0.. тогава seg fault срива програмата. Трябва да е мястото, където Създанието умира, но прекарах толкова много време в опити да го отстраня, а програмите за отстраняване на грешки отказваха да работят. Кълна се, че прекарах 10-15 часа с отстраняване на грешки и никой не ми позволи да стартирам програмата си!
Имам базов клас, Entity, който има 2 производни класа. Тези два производни класа са Предмет и Създание. Тези два подкласа трябва да са обясними.
Очевидно Item има няколко производни класа, които добавят повече специфики за типа Item. Като например Броня, Храна, Оръжие и т.н.
Creature очевидно има неща, които включват реално същество. С това казано, Creature има производен клас, Player, тъй като има само още няколко неща, които Player може да прави.
Някои неща за отбелязване:
Използвам Factory method pattern, който връща указатели за Creatures и друг за Items. Сега съм съсредоточен върху Creature.
В main.cpp създавам един обект Player. След това създавам 3 указателя към Creatures, което е мястото/когато са започнали да се случват грешките в сегментирането. Ето как го имах преди да го сменя, последвано от това как го смених.
Creature * pCreature1 = NULL; Creature * pCreature2 = NULL; Creature * pCreature3 = NULL;
To:
Creature * pCreature1 = new Creature();
Creature * pCreature2 = new Creature();
Creature * pCreature3 = new Creature();
Първият начин ми позволи да направя всичко според очакванията, докато Creature трябва да бъде премахнато от нивото. Промених го на втория начин, защото хората ми казаха, че използвам указателите погрешно.
Код:
Ще добавя част от кода, където мисля, че може да възникнат проблеми. Въпреки това, публикувах този въпрос два пъти и всички ме укориха, че предоставям твърде много код и след това недостатъчен код.. надявам се, че ще задоволя всички и ще направя това по-лесно от това колко непосилно го направих да звучи, ще публикувам там, където < strong>Creature умира тук. Качих всичко в Cloud 9, така че всеки да може да види файловете ми в текущото им състояние и да стартира програмата, за да види къде има грешка.
Класовете, които използват тези указатели и биха могли да причинят грешките, които според мен са:
- main.cpp
- Създание
- Плейър
- Плочка
- DungeonLevel
Опитвам се да не звуча така, сякаш искам някой да ми „даде отговора“, но последните два пъти, когато зададох по същество едно и също търсене, всички ме обвиняват в това. Опитах отстраняване на грешки и никой от програмите за отстраняване на грешки на моя Mac няма да се актуализира. Прекарах часове онази вечер, опитвайки това. Можете да видите тук: Защо стандартната библиотека на c++ не работи?
Това наистина не би трябвало да е толкова сложен проблем. Заседвам в даден момент и нищо, което правя, не намалява грешките :(
Всички мисли, съвети и предложения ще бъдат високо оценени.
Ето връзката към моя проект за облак 9: http://c9.io/moddedlife/jhackpublic
Всичко останало на тази страница ще бъде кодови фрагменти. Благодаря отново!
Метод на атака на играча:
void Player::attack(Creature * monster, Creature * player, std::mt19937 & randomGen, DungeonLevel & dl){
int monsterHit = monster->getHit(randomGen);
int playerHit = getHit(randomGen);
if ((monster->getHP() - playerHit) <= 0){
playerHit = monster->getHP();
cout << "Monster name: " << monster->getName() << endl;
delete monster;
monster = NULL;
cout << "Monster name after: " << monster->getName() << endl;
}
else if ((player->getHP() - monsterHit) <= 0){
monsterHit = player->getHP();
//game over
}
cout << "You hit: " << playerHit << endl;
player->setHP((player->getHP() - monsterHit));
player->addXp(playerHit);
if (monster != NULL){
cout << "Monsters Hit: " << monsterHit << endl;
monster->setHP((monster->getHP() - playerHit));
cout << "Your HP: [" << player->getHP() << "]/[" << player->getMaxHP() << "]" << endl;
cout << "Monsters HP: [" << monster->getHP() << "]/[" << monster->getMaxHP() << "]" << end$
}
else {
cout << "you Killed it!" << endl;
}
return;
}
Метод на преместване на играча:
Щях да сложа целия този код, но по същество е един и същ - само посоката се променя... всяка посока е около 30-50 реда. Можете да видите целия код за който и да е от моите файлове тук: http://c9.io/moddedlife/jhackpublic
ЩЕ добавя кода тук, ако използването на облак 9 не е разрешено или нещо подобно. Просто си помислих, че това ще го направи много по-лесно от поставянето на блокове от няколко файла.
Благодаря
new
навсякъде. Ако използвате указатели, трябва да използвате и интелигентни указатели, които всъщност са класове обвивки, които предотвратяват няколко често срещани грешки. - person Ulrich Eckhardt   schedule 28.04.2013