Zugriffsverletzung und fehlerhaftes Verhalten

  • C/C++

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Zugriffsverletzung und fehlerhaftes Verhalten

    Da ich längere Zeit nicht mehr mit c++ gearbeitet habe wollte ich ein einfaches Programm mit nichts besonderem zum reinkommen programmieren. Nun bin ich an einem Punkt angekommen wo ich vor lautern Zeigern den Zeigerwald nicht mehr sehe. Der Fehler tritt unter Bestimmten Umständen auf wenn ich bei der Klasse CREATURE die virtuelle Funktion c_move() aufrufen möchte. Genauer gesagt hängt es sich daran auf wenn ich auf den parent_field Zeiger zugreifen möchte. Es erscheint folgende Nachricht:
    Unbehandelte Ausnahme bei 0x00A86B76 in Symbiose.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xFEEEFEEE

    Damit ich erklären kann wann dieser Fehler unter welchen Umständen auftritt, kurz gesagt was ich Vorhabe. Ich habe ein zweidimensionales Feld. Auf diesem Feld kann man mit der rechten Maustaste Lustige Hasen erstellen. Dazu wird der FIELD_CELL ein Pointer von der Vererbten Klasse CREATURE der neu erstellten Instanz RABBIT hinzugefügt. Soweit funktioniert alles wunderbar. In der Klasse steht das es drei ultra niedliche Hasen sind. Nun soll ein Hase jeden Feldes, sofern sie vorhanden sind, nach rechts wandern, sobald man die linke Maustaste drückt. Klappt auch ganz gut ohne Fehler. Es bleiben zwei Hasen zurück und rechts daneben erscheint der Hase der "umgezogen" ist. Dafür wird eine neue Gruppeninstanz erzeugt. Existiert auf diesem Feld schon ein Hase, auch kein Problem. Der Hase wird einfach den anderen Hasen dazugezählt. Drückt man erneut die Taste, wandert zwar noch ein Hase nach rechts von dem Feld aus das wir mit der rechten Maustaste erstellt haben, aber es wandert kein Hase aus der resultirten Hasengruppe. Diese bleiben einfach stehen. Drückt man jetzt nochmal die rechte Maustaste, bleibt kein Hase mehr zurück und die Instanz wird gelöscht und die FIELD_CELL mit der next_id überschrieben, die den Null-Zeiger entahlten sollte, da ja keine andere Tierart sich dort befindet. Und welch ein Glück! Die Fehlermeldung erscheint und meckert bei Zeile 540 rum. Dort wird nur die Virtuell vererbte Funktion aufgerufen, daran liegt es aber nicht. Ich bin überfordert und weiß nicht wo der Fehler liegt. Nachfolgender Code kann problemlos als Win32-Anwendung ohne jegliche bibliotheken ausgeführt werden. Achtung! Sie öffnen den Spoiler auf eigener Gefahr!
    Spoiler anzeigen

    C-Quellcode

    1. #include <windows.h>
    2. #include <Strsafe.h>
    3. #include <wchar.h>
    4. #include <commctrl.h>
    5. const COLORREF WindowColor = RGB(240,240,240);
    6. const int CREATURE_NAME_LENGTH = 64;
    7. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    8. LRESULT WndProc_cell_label(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
    9. LRESULT WndProc_main_field(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
    10. HWND hWnd_listbox;
    11. HINSTANCE hInst_listbox;
    12. class FIELD_CELL;
    13. class CREATURE
    14. {
    15. protected:
    16. virtual void vc_init(){};
    17. virtual void vc_move(){};
    18. virtual void vc_fight(){};
    19. virtual void vc_live(){};
    20. public:
    21. unsigned int id;
    22. CREATURE* next_id;
    23. FIELD_CELL* parent_field;
    24. int creatures_number;
    25. wchar_t name[CREATURE_NAME_LENGTH];
    26. void c_move_set(int move_x, int move_y, int moving_creatures);
    27. void c_init();
    28. void c_move();
    29. void c_fight();
    30. void c_live();
    31. void move_creature(int new_pos_x, int new_pos_y, int number_of_moving);
    32. };
    33. #define ID_NULL 0
    34. #define ID_BEAR 1
    35. class BEAR : public CREATURE
    36. {
    37. public:
    38. void vc_init();
    39. void vc_move();
    40. void vc_fight();
    41. void vc_live();
    42. };
    43. #define ID_RABBIT 2
    44. class RABBIT : public CREATURE
    45. {
    46. public:
    47. void vc_init();
    48. void vc_move();
    49. void vc_fight();
    50. void vc_live();
    51. };
    52. class TERRAIN
    53. {
    54. protected:
    55. int terrain;
    56. public:
    57. virtual void update_label() = NULL;
    58. int get_terrain();
    59. void set_terrain(int terrain_new_val);
    60. };
    61. class FIELD_CELL : public TERRAIN
    62. {
    63. private:
    64. bool b_n_c;
    65. int pos_x;
    66. int pos_y;
    67. HINSTANCE hInst_label;
    68. void create_label();
    69. public:
    70. CREATURE* first_creature;
    71. HWND hWnd_label;
    72. WNDPROC WndProc_cell_label_def;
    73. void update_label();
    74. void update_listbox();
    75. void init(int x, int y);
    76. int get_pos_x();
    77. int get_pos_y();
    78. virtual LRESULT action(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
    79. HWND get_hWnd_label();
    80. void create_creature(CREATURE* new_creature);
    81. CREATURE* find_creature(unsigned int creature_id);
    82. CREATURE* unlock_creature(unsigned int creature_id);
    83. void move_all_creatures();
    84. };
    85. class MAIN_FIELD
    86. {
    87. private:
    88. FIELD_CELL* cell;
    89. FIELD_CELL* null_cell;
    90. int cells_w;
    91. int cells_h;
    92. public:
    93. HWND hWnd;
    94. HINSTANCE hInstance;
    95. WNDPROC WndProc_main_field_def;
    96. void create_field(int width, int height);
    97. FIELD_CELL* get_cell(int x, int y);
    98. FIELD_CELL* get_cell(int pos);
    99. int get_cells_w();
    100. int get_cells_h();
    101. FIELD_CELL* get_cell_by_hWnd_label(HWND search_hWnd);
    102. void resize_window();
    103. void move_all();
    104. };
    105. MAIN_FIELD *main_field;
    106. void register_window(HINSTANCE hInstance)
    107. {
    108. WNDCLASSEX wcex;
    109. wcex.cbSize = sizeof(WNDCLASSEX);
    110. wcex.style = CS_HREDRAW | CS_VREDRAW;
    111. wcex.lpfnWndProc = WndProc;
    112. wcex.cbClsExtra = 0;
    113. wcex.cbWndExtra = 0;
    114. wcex.hInstance = hInstance;
    115. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    116. wcex.hIcon = NULL;
    117. wcex.hbrBackground = CreateSolidBrush(WindowColor);
    118. wcex.lpszMenuName = NULL;
    119. wcex.lpszClassName = L"SYMBIOSE_PROGRAMM";
    120. wcex.hIconSm = NULL;
    121. RegisterClassEx(&wcex);
    122. }
    123. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    124. {
    125. MSG msg;
    126. HWND hWnd;
    127. register_window(hInstance);
    128. hWnd = CreateWindowEx(0,
    129. L"SYMBIOSE_PROGRAMM",
    130. L"Symbiose",
    131. WS_OVERLAPPEDWINDOW,
    132. (int)((GetSystemMetrics(SM_CXSCREEN)-(512))*0.5f),
    133. (int)((GetSystemMetrics(SM_CYSCREEN)-(384))*0.5f),
    134. (1024),
    135. (768),
    136. NULL,
    137. NULL,
    138. hInstance,
    139. NULL);
    140. if (!hWnd)
    141. {
    142. MessageBox(NULL, L"Error by creating window.", L"Symbiose", MB_ICONERROR);
    143. return false;
    144. }
    145. hWnd_listbox = CreateWindow(WC_STATIC,L"",WS_VISIBLE | WS_CHILD | WS_BORDER,0,0,0,0,hWnd,NULL,hInst_listbox,NULL);
    146. HFONT hFont = CreateFont(24,0,GM_COMPATIBLE,NULL,0,false,false,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_DONTCARE,L"Microsoft Sans Serif");
    147. SendMessage(hWnd_listbox, WM_SETFONT, (WPARAM) hFont, TRUE);
    148. main_field = new MAIN_FIELD;
    149. main_field->hWnd = CreateWindow(L"static",L"",WS_VISIBLE | WS_CHILD,8,8,768,384,hWnd,(HMENU)0,main_field->hInstance,NULL);
    150. main_field->WndProc_main_field_def = (WNDPROC)SetWindowLong( main_field->hWnd, GWL_WNDPROC, (LONG_PTR)WndProc_main_field);
    151. main_field->create_field(10, 10);
    152. for(int i = 0; i < main_field->get_cells_w()*main_field->get_cells_h(); i++)
    153. main_field->get_cell(i)->set_terrain(0);
    154. ShowWindow(hWnd, nCmdShow);
    155. UpdateWindow(hWnd);
    156. while (GetMessage(&msg, NULL, 0, 0))
    157. {
    158. TranslateMessage(&msg);
    159. DispatchMessage(&msg);
    160. }
    161. return (int) msg.wParam;
    162. }
    163. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    164. {
    165. RECT borders;
    166. GetClientRect(hWnd, &borders);
    167. switch (message)
    168. {
    169. case WM_GETMINMAXINFO:
    170. {
    171. const POINT mitracksize = {1024, 768};
    172. ((PMINMAXINFO)lParam)->ptMinTrackSize = mitracksize;
    173. }
    174. break;
    175. case WM_SIZE:
    176. MoveWindow(main_field->hWnd, 8, 8, borders.right-8-8-8-192, borders.bottom-16, false);
    177. MoveWindow(hWnd_listbox, borders.right-192-8, 8, 192, borders.bottom-16, true);
    178. break;
    179. case WM_DESTROY:
    180. PostQuitMessage(0);
    181. break;
    182. default:
    183. return DefWindowProc(hWnd, message, wParam, lParam);
    184. }
    185. return 0;
    186. }
    187. void MAIN_FIELD::create_field(int width, int height)
    188. {
    189. cells_w = width;
    190. cells_h = height;
    191. cell = new FIELD_CELL[width*height];
    192. for(int ix = 0; ix < width; ix++)
    193. for(int iy = 0; iy < height; iy++)
    194. {
    195. get_cell(ix, iy)->init(ix, iy);
    196. get_cell(ix, iy)->update_label();
    197. }
    198. null_cell = new FIELD_CELL;
    199. null_cell->init(-1, -1);
    200. }
    201. FIELD_CELL* MAIN_FIELD::get_cell(int x, int y)
    202. {
    203. if(x >= 0 && x < cells_w && y >= 0 && y < cells_h)
    204. return cell+x+y*cells_w;
    205. else
    206. return null_cell;
    207. }
    208. FIELD_CELL* MAIN_FIELD::get_cell(int pos)
    209. {
    210. return cell+pos;
    211. }
    212. FIELD_CELL* MAIN_FIELD::get_cell_by_hWnd_label(HWND search_hWnd)
    213. {
    214. for(int i = 0; i < cells_w*cells_h; i++)
    215. {
    216. if((cell+i)->hWnd_label == search_hWnd)
    217. return cell+i;
    218. }
    219. return null_cell;
    220. }
    221. void FIELD_CELL::create_label()
    222. {
    223. RECT borders;
    224. GetClientRect(main_field->hWnd, &borders);
    225. borders.left = (borders.right/main_field->get_cells_w());
    226. borders.top = (borders.bottom/main_field->get_cells_h());
    227. hWnd_label = CreateWindow(WC_BUTTON , L"", WS_CHILD | WS_VISIBLE | SS_CENTER, pos_x*borders.left, pos_y*borders.top, borders.left, borders.top, main_field->hWnd, (HMENU)(pos_x*pos_y), hInst_label, NULL);
    228. WndProc_cell_label_def = (WNDPROC)SetWindowLong( hWnd_label, GWL_WNDPROC, (LONG_PTR) WndProc_cell_label);
    229. HFONT hFont = CreateFont(16,0,GM_COMPATIBLE,NULL,0,false,false,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_DONTCARE,L"Microsoft Sans Serif");
    230. SendMessage(hWnd_label, WM_SETFONT, (WPARAM) hFont, TRUE);
    231. }
    232. void FIELD_CELL::init(int x, int y)
    233. {
    234. b_n_c = x < 0 || y < 0;
    235. pos_x = x;
    236. pos_y = y;
    237. terrain = -1;
    238. first_creature = NULL;
    239. create_label();
    240. }
    241. int FIELD_CELL::get_pos_x()
    242. {
    243. return pos_x;
    244. }
    245. int FIELD_CELL::get_pos_y()
    246. {
    247. return pos_y;
    248. }
    249. HWND FIELD_CELL::get_hWnd_label()
    250. {
    251. return hWnd_label;
    252. }
    253. void FIELD_CELL::update_label()
    254. {
    255. wchar_t result_text[255];
    256. wchar_t buf[16];
    257. if( first_creature != NULL)
    258. {
    259. CREATURE* nsid = first_creature;
    260. wcscpy_s(result_text, 255, L"");
    261. while(nsid != NULL)
    262. {
    263. _itow_s(nsid->creatures_number, buf, 8, 10);
    264. wcscat_s(result_text, 255, buf);
    265. wcscat_s(result_text, 255, L"x ");
    266. wcscat_s(result_text, 255, nsid->name);
    267. wcscat_s(result_text, 255, L"; \n");
    268. nsid = nsid->next_id;
    269. }
    270. }
    271. else
    272. {
    273. wcscpy_s(result_text, 255, L"NO LIVE");
    274. }
    275. SetWindowTextW(hWnd_label, result_text);
    276. }
    277. void FIELD_CELL::update_listbox()
    278. {
    279. wchar_t result_text[255];
    280. wchar_t buf[16];
    281. if( first_creature != NULL)
    282. {
    283. CREATURE* nsid = first_creature;
    284. wcscpy_s(result_text, 255, L"");
    285. while(nsid != NULL)
    286. {
    287. _itow_s(nsid->creatures_number, buf, 8, 10);
    288. wcscat_s(result_text, 255, buf);
    289. wcscat_s(result_text, 255, L"x ");
    290. wcscat_s(result_text, 255, nsid->name);
    291. wcscat_s(result_text, 255, L"; \n");
    292. nsid = nsid->next_id;
    293. }
    294. }
    295. else
    296. wcscpy_s(result_text, 255, L"Dies ist eine ziemlich trostlose Umgebung.");
    297. SetWindowTextW(hWnd_listbox, result_text);
    298. }
    299. void TERRAIN::set_terrain(int terrain_new_val)
    300. {
    301. terrain = terrain_new_val;
    302. update_label();
    303. }
    304. int TERRAIN::get_terrain()
    305. {
    306. return terrain;
    307. }
    308. int MAIN_FIELD::get_cells_w()
    309. {
    310. return cells_w;
    311. }
    312. int MAIN_FIELD::get_cells_h()
    313. {
    314. return cells_h;
    315. }
    316. LRESULT FIELD_CELL::action(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    317. {
    318. switch(message)
    319. {
    320. case WM_LBUTTONUP:
    321. {
    322. main_field->move_all();
    323. update_listbox();
    324. }
    325. break;
    326. case WM_RBUTTONUP:
    327. {
    328. CREATURE* ncre = new RABBIT;
    329. ncre->c_init();
    330. ncre->parent_field = this;
    331. create_creature(ncre);
    332. update_listbox();
    333. }
    334. break;
    335. }
    336. return CallWindowProc( WndProc_cell_label_def, hWnd, message, wParam, lParam );
    337. }
    338. void MAIN_FIELD::resize_window()
    339. {
    340. HWND ghWndlabel;
    341. RECT borders;
    342. GetClientRect(main_field->hWnd, &borders);
    343. borders.left = (borders.right/cells_h);
    344. borders.top = (borders.bottom/cells_w);
    345. int bw;
    346. int bh;
    347. for(int ix = 0; ix < cells_w; ix++)
    348. for(int iy = 0; iy < cells_h; iy++)
    349. {
    350. ghWndlabel = get_cell(ix, iy)->get_hWnd_label();
    351. if(ix == cells_w-1)
    352. bw = borders.right-(ix*borders.left);
    353. else
    354. bw = borders.left;
    355. if(iy == cells_h-1)
    356. bh = borders.bottom-(iy*borders.top);
    357. else
    358. bh = borders.top;
    359. MoveWindow(ghWndlabel, ix*borders.left, iy*borders.top, bw, bh, true);
    360. }
    361. }
    362. LRESULT WndProc_main_field( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    363. {
    364. switch(message)
    365. {
    366. case WM_SIZE:
    367. main_field->resize_window();
    368. break;
    369. default:
    370. return CallWindowProc( main_field->WndProc_main_field_def, hWnd, message, wParam, lParam );
    371. }
    372. return CallWindowProc( main_field->WndProc_main_field_def, hWnd, message, wParam, lParam );
    373. }
    374. LRESULT WndProc_cell_label( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    375. {
    376. FIELD_CELL *gc = main_field->get_cell_by_hWnd_label(hWnd);
    377. gc->action(hWnd, message, wParam, lParam );
    378. return CallWindowProc( gc->WndProc_cell_label_def, hWnd, message, wParam, lParam );
    379. }
    380. void FIELD_CELL::create_creature(CREATURE* new_creature)
    381. {
    382. CREATURE* new_searched_id = first_creature;
    383. CREATURE* pre_searched_id = NULL;
    384. while(new_searched_id != NULL && new_searched_id->id != new_creature->id)
    385. {
    386. pre_searched_id = new_searched_id;
    387. new_searched_id = new_searched_id->next_id;
    388. }
    389. if(new_searched_id == NULL)
    390. {
    391. new_searched_id = new_creature;
    392. new_searched_id->parent_field = this;
    393. if(pre_searched_id != NULL)
    394. pre_searched_id->next_id = new_searched_id;
    395. else
    396. first_creature = new_searched_id;
    397. }
    398. else
    399. {
    400. new_searched_id->creatures_number += new_creature->creatures_number;
    401. delete new_creature;
    402. new_creature = NULL;
    403. }
    404. update_label();
    405. }
    406. void BEAR::vc_init()
    407. {
    408. id = ID_BEAR;
    409. creatures_number = 2;
    410. wcscpy_s(name, CREATURE_NAME_LENGTH, L"Bär");
    411. }
    412. void BEAR::vc_fight() {}
    413. void BEAR::vc_move() {}
    414. void BEAR::vc_live() {}
    415. void RABBIT::vc_init()
    416. {
    417. id = ID_RABBIT;
    418. creatures_number = 3;
    419. wcscpy_s(name, CREATURE_NAME_LENGTH, L"Hase");
    420. }
    421. void RABBIT::vc_fight() {}
    422. void RABBIT::vc_move()
    423. {
    424. FIELD_CELL* pf = parent_field;
    425. move_creature(pf->get_pos_x()+1,pf->get_pos_y(),1);
    426. }
    427. void RABBIT::vc_live() {}
    428. void CREATURE::c_init()
    429. {
    430. next_id = NULL;
    431. vc_init();
    432. }
    433. void CREATURE::move_creature(int new_pos_x, int new_pos_y, int number_of_moving)
    434. {
    435. if(number_of_moving >= creatures_number)
    436. {
    437. main_field->get_cell(new_pos_x, new_pos_y)->create_creature(parent_field->unlock_creature(id));
    438. }
    439. else
    440. {
    441. CREATURE* ncopcre = new CREATURE;
    442. ncopcre->creatures_number = number_of_moving;
    443. ncopcre->id = this->id;
    444. ncopcre->parent_field = main_field->get_cell(new_pos_x, new_pos_y);
    445. wcscpy_s(ncopcre->name, CREATURE_NAME_LENGTH, name);
    446. this->creatures_number -= number_of_moving;
    447. main_field->get_cell(new_pos_x, new_pos_y)->create_creature(ncopcre);
    448. parent_field->update_label();
    449. parent_field->update_listbox();
    450. }
    451. }
    452. void CREATURE::c_move()
    453. {
    454. vc_move();
    455. }
    456. CREATURE* FIELD_CELL::find_creature(unsigned int creature_id)
    457. {
    458. CREATURE* new_searched_id = first_creature;
    459. CREATURE* creature_found = NULL;
    460. while(new_searched_id != NULL)
    461. {
    462. if(new_searched_id->id == creature_id)
    463. creature_found = new_searched_id;
    464. new_searched_id = new_searched_id->next_id;
    465. }
    466. return creature_found;
    467. }
    468. CREATURE* FIELD_CELL::unlock_creature(unsigned int creature_id)
    469. {
    470. CREATURE* new_searched_id = first_creature;
    471. CREATURE* creature_found = NULL;
    472. CREATURE* creature_last = NULL;
    473. while(new_searched_id != NULL)
    474. {
    475. if(new_searched_id->id == creature_id)
    476. {
    477. if(creature_last == NULL)
    478. {
    479. first_creature = new_searched_id->next_id;
    480. }
    481. else
    482. creature_last->next_id = new_searched_id->next_id;
    483. creature_found = new_searched_id;
    484. creature_found->next_id = NULL;
    485. break;
    486. }
    487. creature_last = new_searched_id;
    488. new_searched_id = new_searched_id->next_id;
    489. }
    490. update_label();
    491. return creature_found;
    492. }
    493. void MAIN_FIELD::move_all()
    494. {
    495. for(unsigned short ix = 0; ix < cells_w; ix++)
    496. for(unsigned short iy = 0; iy < cells_h; iy++)
    497. {
    498. get_cell(ix, iy)->move_all_creatures();
    499. }
    500. }
    501. void FIELD_CELL::move_all_creatures()
    502. {
    503. CREATURE* new_searched_id = first_creature;
    504. while(new_searched_id != NULL)
    505. {
    506. new_searched_id->c_move();
    507. new_searched_id = new_searched_id->next_id;
    508. }
    509. }
    Alles anzeigen

    Was könnte der Fehler sein? Was aber viel wichtiger ist, was könnte ich generell besser machen um solche Fehler zu vermeiden? Konstruktive Kritik an meinen Code ist auch erwünscht. Ich wäre bei Hilfe unendlich dankbar.
  • Bei mir knallt das erstmal an ganz anderer Stelle: Wenn ich auf eines der Felder rechtsklicke, werden dort drei Hasen erzeugt. Wenn ich danach auf irgend ein Feld linksklicke, gibt es eine ähnliche Zugriffsverletzung.
    Ich hab mich dann mal im Debugger den Callstack von der Fehlermeldung aus aufwärts gehangelt, und folgendes gefunden:

    Irgendwann wird FIELD_CELL::create_creature(CREATURE* new_creature) mit new_creature = 0x003c03d8 gerufen. Genau diesen Wert hat zu der Zeit auch der Zeiger FIELD_CELL::first_creature und durch die Zuweisung in der ersten Zeile dieser Funktion anschließend auch der Zeiger new_search_id.
    D.h. weil new_search_id nun den gleichen Wert hat, wie new_creature, stimmen auch deren IDs überein (sind schließlich das selbe Objekt), so dass die while-schleife nicht betreten wird.
    new_search_id ist nicht NULL, also geht es danach im else-Zweig der Bedingung weiter.
    Nachdem auf new_seach_id->creature_number etwas drauf addiert wurde, wird auf new_creature (== new_search_id == first_creature) delete aufgerufen.
    ANschließend wird die Funktion update_label() gerufen.

    Das Objekt, auf das first_creature mal gezeigt hat, ist zwar nun freigegeben worden, aber der Zeiger zeigt immer noch auf diese Adresse, ist also ungleich NULL, d.h. wir betreten dort den then-Zweig der Bedingung.
    Der Zeiger nsid zeigt nun auf die gleiche Adresse, wie first_creature (immer noch ein bereits freigegebener bereich des Speichers), ist also auch nicht NULL, so dass wir die while-Schleife betreten.
    Und dort soll dann als erster Parameter des ersten Funktionsaufrufs nsid->creature_number abgefragt werden.
    Mag sein, dass andere Umgebungen es zulassen, dass man aus schon freigegebenen Speicherbereichen noch etwas auslesen kann, aber bei mir gibt es dann halt eine Zugriffsverletzung.

    Aufgrund dessen kann ich jedenfalls den von dir beschriebenen Fehler gar nicht erst reproduzieren...

    Zu der frage, was du generell besser machen kannst: Zunächst einmal fand ich deinen Stil etwas gewöhnungsbedürftig, alle Typen nur in Großbuchstaben zu schreiben; üblicherweise bezeichnen Symbole, die nur aus Großbuchstaben bestehen, Konstanten oder Makros.
    Aber viel wichtiger: Kommentier deinen Code mal. Abkürzungen wie nsid oder Bezeichnungen wir new_creature, first_creature, etc. mögen dir jetzt noch irgendwas sagen, und du magst jetzt auch vllt. noch im Kopf haben, welche Funktion was tun soll und wann aufgerufen werden muss, aber lass das Projekt mal auf eine gewisse Größe anwachsen oder lass es mal ein Jahr liegen, und dann wirst du selbst Probleme bekommen, dich darin zurechtzufinden.
  • Ich bin meinen Code nochmal durchgegangen und nochmal compiliert. Ich habe nichts daran geändert. Jetzt treten andere Merkwürdige Verhalten auf, aber diesmal ohne Zugriffsverletzung. Rein theoretisch ist new_creature nur ein temporär erstelltes Objekt, welches entweder gelöscht wird wenn eins gleicher Art vorhanden ist, oder zugewiesen wird wenn noch keins existiert. Heißt dein beschriebener Fehler könnte nur auftreten wenn die Funktion CREATURE::move_creature() auf die selbe Stelle mit allen Einheiten zeigt. Generell scheint der Code machen zu wollen, was er will. Ich glaube es hilft nur noch den Code komplett neu zu schreiben und dann Strukturierter und Übersichtlicher und nicht so als müsste man irgendwelche Rituale schreiben um eine Funktion aufzurufen. Ich bedanke mich vielmals für deine Hilfe.
  • Benutzer online 1

    1 Besucher