Ko'rsatkichlarni belgilash va yo'q qilish

OK, shuning uchun konteks. Men afsungarlikdagi 8 ta jumboq muammosiga ishlaydigan deyarli bir kun turdim. Mening hisobotimni pastga tushiraman va mening A_star algoritmi pastga tushadi. Biz loyiha spektrlari yordamida uni uch xil sezgir qadriyatlardan foydalanib hal qilishimiz kerak. Men buni uch kishidan har biri uchun hal qila olaman, lekin ularni ketma-ket echish uchun ketganimda, kulgili aylana olaman va hech qachon to'g'ri hal qiluvchi davlatni topa olmaydi.

Men ishonaman muammo mening ko'rsatgichlarim bilan. Menda bir sinf mavjud, davlat quyida tavsiflanganidek, int ** qatori va davlatga (uning ota-onasiga) ishora qiladi.

Edit: men loyiha spetsifikatsiyasi bilan aniqlangan int ** ni ishlatishim kerak, aks holda men mamnuniyat bilan foydalanmoqchiman.

State   (int **bd, State* prnt);
State   (const State& other);
~State  ();

Men ularni shunday deb e'lon qilaman:

State::State(int **bd, State* prnt) {

// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];
}

// fill in the board
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        board[i][j] = bd[i][j];
        //board[i][j] = 
    }
}

// set the parent
parent = prnt;

}

State::State(const State& other) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];

State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
    delete board[i];
delete [] board;
delete parent;
parent = other.parent;

}

State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
    delete board[i];
delete [] board;
delete parent;

}

State& State::operator=(const State &rhs) {
if (&rhs == this) {
    return *this;
}

for (int i = 0; i < 3; i++) {
    delete board[i];
}
delete [] board;

// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];
}

// fill in the board
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        //board[i][j] = rhs.board[i][j];
        board[i][j] = rhs.getIntAtCoor(j, i);
    }
}

//delete parent;
// set the parent
parent = rhs.parent;

// set g
g = rhs.g;
f = rhs.f;
hType = rhs.hType;

return *this;

}

Men aniq tushunchalarni bermayman - ba'zi int = int kabi oddiy. Buni faqat tushunish mumkin emas. Men o'zimni ota-sahifani o'chirib tashlashni xohlamadim yoki o'zimning ota-ona = boshqa.parent noto'g'ri (yoki har ikkalasi) kabi his qilaman.

Vaqtingiz va yordamingiz uchun tashakkur,

Tyler

2
Siz markerni yo'q qila olmaysiz, markerni o'chirasiz, ko'rsatgich ko'rsatadigan ob'ekt.
qo'shib qo'ydi muallif mloskot, manba
@deft_code Mening sharhlarimda hech qanday pedantik narsa yo'q. Ishlarni to'g'ri va aniq bajarish ularni tushunishga yordam beradi. Bundan tashqari, agar siz ishlayotgan domen terminologiyasidan foydalanmasangiz, siz o'zingizning oyog'ingizga o'q uzishingiz mumkin.
qo'shib qo'ydi muallif mloskot, manba
Zamonaviy C ++ da siz new operatoridan qoching va hech qachon delete operatoridan foydalanmasligingiz kerak. Shubhasiz, bu, albatta, past darajadagi materiallarga taalluqli emas (ajratuvchilar, xotira havzalari, aqlli ko'rsatkichlar va boshqalar), lekin ularni tez-tez yozishmaydi.
qo'shib qo'ydi muallif deft_code, manba
@mloskot: Agar haqiqatdan ham pendantic ni olishni istasangiz: bajaring markerni yo'q qilasiz, faqat deallocate nuqtasi. Har ikki holatda ham pedantik ko'krak qafaslari hech kimga yordam bermaydi.
qo'shib qo'ydi muallif deft_code, manba
Bundan tashqari, bizga operator = sekin
qo'shib qo'ydi muallif Mooing Duck, manba
Dinamik massivlardan foydalanmang. Uning o'rniga std :: vector dan foydalaning.
qo'shib qo'ydi muallif Cat Plus Plus, manba
@deft_code OK, shuning uchun faqatgina ota-kodni o'chirib tashlashimning barcha misollarini o'chirib tashlashni istayman, lekin int ** orqali yinelamani va har bir xonimni o'chirib tashlash misollari haqida nima desa bo'ladi? U erda ham yo'q qilishni xohlaymanmi?
qo'shib qo'ydi muallif Tyler Bell, manba

3 javoblar

Kod-uslubingizni yangilash xatolar bug'lanib ketishiga majbur qilishi mumkin. Boshqacha aytganda new va delete xatolarga moyil bo'lib, yaxshi alternativ mavjud bo'lganda yo'l qo'ymaslik kerak.

Hujayralarni boshqarish uchun quyidagilarni hisobga oling:

  • std::shared_ptr: can be used to void the delete calls
  • std::vector can be used to avoid the new and delete calls
    Note you should use it like std::vector board( 3 * 3 ) and board.at( x + y * 3 ).
  • And best of all just use a static array int board[3][3]. No allocation at all.

Also child states do not own their parent states. It's the other way around. So child states shouldn't delete their parents. You can still safely keep a parent pointer, but make sure you cleanup the children before you allow a parent to go out of scope (deleted or otherwise). All of this cleaning and deleting doesn't neccessarily involve new at all. Your State class looks small enough that is doesn't matter if they are copied by value. In which case just have the parent use a std::vector m_children and the compiler will take care of the rest.

2
qo'shib qo'ydi
Matrix sifatida foydalanish uchun std :: vector > ni tavsiya qilmaganingiz uchun tashakkur. Ma'lumotlarning joylashuvi ehtimol qo'rqinchli va ishlashi sezilarli darajada kamaydi. Ya'ni, pastki datchada at() dan foydalanmang. da() chegara nazoratini amalga oshiradi. Albatta, bu kodning ish faoliyatini sezgir bo'lganiga bog'liq.
qo'shib qo'ydi muallif Ed S., manba
@TylerBell: barcha delete chaqiruvlarini izohlab bo'lgach kodingizni ishlatishga urinib ko'ring. Bu xotirani tasdiqlaydigan xatoliklarni to'g'rilab qo'yishini tekshiring. Bundan tashqari, ta'rif qilayotgan xatti-harakatlar sizning noto'g'ri gapingiz bo'lgan global yoki statik o'zgaruvchiga o'xshaydi.
qo'shib qo'ydi muallif deft_code, manba
Buni hamma kodni ota-kodni o'chirib tashlamasdan yozdim va uni ketma-ket uch xil heuristics bilan ishlashga harakat qilgunga qadar jarima ishladi. Bu birinchi darajali nozik jarima ishini tugatadi, lekin ikkinchisiga yopishib qoladi. Ushbu xulq-atvorga olib kelishi mumkin bo'lgan har qanday bayonotda biror narsani ko'rasizmi?
qo'shib qo'ydi muallif Tyler Bell, manba

Nusxa ko'chirish sozlovchisining to'liq ta'rifini ko'rsatsangiz-da, parent = other.parent qatori o'sha erda. Bunday holatda, ota-ona o'z hayoti uchun mas'ul emas va halokatdagi ota-onani yo'q qilish hech bo'lmasa bo'lishi kerak.

Shuni ham unutmangki, hech bo'lmaganda o'chirib qo'ying (xususiy deklaratsiya) yoki nusxa ko'chirish tayinlash operatorini qo'llash kerak.

Bundan tashqari, 2d qator uchun vector vector dan foydalaning va til siz uchun ishlashi mumkin.

1
qo'shib qo'ydi
Kechirasiz, uni qo'shib qo'yishni unutganman, lekin tayinlov operatori bor. Men uni yuqoridagi lavozimga qo'shdim. Va, albatta, men vektordan foydalanishim mumkinligini xohlayman, lekin buni aniq belgilab olamiz (CS tayinlashi). :-(
qo'shib qo'ydi muallif Tyler Bell, manba

Ehtimol, to'g'ridan-to'g'ri javob emas, balki C ++ uchun eng yaxshi amaliyotlarga qarshi.

Bu muammoni hal qilish uchun vektorlardan foydalanish osonroq va, albatta, yanada chidamli.

size_t row_sz = 3;
size_t col_sz = 3;
std::vector board(row_sz * col_sz, 0);

int i = 0;
for (size_t r = 0; r < 0; r++)
for (size_t c = 0; c < 0; c++)
  board[ r * row_sz + c ] = i++;

Ko'p o'lchovli massivlar yuqoridagi strategiya bilan ham osonroq ishlaydi. Bu ozgina bo'linadi. Agar siz chindan ham satr/kol kirishni xohlasangiz, uning atrofida sariq yozing.

struct Matrix {
  int &operator()(size_t r, size_t c);
  const int &operator()(size_t r, size_t c) const;

private:
  std::vector data;
};
0
qo'shib qo'ydi
@TylerBell Xo'sh, kimdir googlega qoqilib ketgan taqdirda. Nimaga kerak, sanoatda hech kim sizdan umuman foydalanmaslikni so'ramaydi. Agar kodni interfeys bilan tekshirsam, hatto toqat qilolmasligim kerak. .
qo'shib qo'ydi muallif Tom Kerr, manba
Men ma'lumotni kiritish uchun savolimni tahrir qildim, menga yanada aniqroq bo'lish uchun rahmat! :: Biz int ** dan foydalanish uchun spetsifikatsiyani talab qilamiz. :-(
qo'shib qo'ydi muallif Tyler Bell, manba