我正在用C ++编写游戏。 我遇到了一个错误,我还没有发现它的来源。
每当我尝试访问CollisionEngine类的私有成员时,我都会遇到seg错误。 通过这个在CollisionEngine的一个成员函数中使用像this-> is_previous_collision_x这样的命令。
这是valgrind输出:
==23949== Memcheck, a memory error detector
==23949== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==23949== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==23949== Command: ./main
==23949==
==23949== Thread 2:
==23949== Syscall param writev(vector[...]) points to uninitialised byte(s)
==23949== at 0x5CCB84D: ??? (in /usr/lib/libc-2.22.so)
==23949== by 0x72E7DA8: ??? (in /usr/lib/libxcb.so.1.1.0)
==23949== by 0x72E819C: ??? (in /usr/lib/libxcb.so.1.1.0)
==23949== by 0x72E8224: xcb_writev (in /usr/lib/libxcb.so.1.1.0)
==23949== by 0x6FDD18D: _XSend (in /usr/lib/libX11.so.6.3.0)
==23949== by 0x6FDD681: _XReply (in /usr/lib/libX11.so.6.3.0)
==23949== by 0x6FC8406: XInternAtom (in /usr/lib/libX11.so.6.3.0)
==23949== by 0x4EEBE9B: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4EECC8A: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4EDF55F: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4EDF36F: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4E475FE: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== Address 0x640d863 is 35 bytes inside a block of size 16,384 alloc'd
==23949== at 0x4C2A987: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23949== by 0x6FCD4E1: XOpenDisplay (in /usr/lib/libX11.so.6.3.0)
==23949== by 0x4EEACB4: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4EDF330: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x4E475FE: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x40488D: Game::game_loop() (Game.cpp:131)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== Uninitialised value was created by a stack allocation
==23949== at 0x6FD87C0: XStoreColors (in /usr/lib/libX11.so.6.3.0)
==23949==
==23949== Invalid read of size 4
==23949== at 0x40266A: GameWindow::get_pixel_color(SDL_Surface*, int, int) (GameWindow.cpp:174)
==23949== by 0x40418C: CollisionEngine::collision_check_wall(GameState*, Character*) (CollisionEngine.cpp:83)
==23949== by 0x404022: CollisionEngine::collision_check_player(GameState*) (CollisionEngine.cpp:35)
==23949== by 0x403F4C: CollisionEngine::collision_check(GameState*) (CollisionEngine.cpp:12)
==23949== by 0x404C1B: Game::advance_actual_state() (Game.cpp:276)
==23949== by 0x40490A: Game::game_loop() (Game.cpp:145)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== Address 0x63b2a10 is 0 bytes after a block of size 96 alloc'd
==23949== at 0x4C2A987: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23949== by 0x4EDA0FF: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x403800: Graphics::surface_copy(SDL_Surface*) (Graphics.cpp:80)
==23949== by 0x4035EC: Graphics::get_map(GID) (Graphics.cpp:31)
==23949== by 0x401FC8: GameWindow::GameWindow(Graphics*, GameState*) (GameWindow.cpp:15)
==23949== by 0x404511: Game::Game() (Game.cpp:47)
==23949== by 0x404C45: main (main.cpp:39)
==23949==
==23949== Invalid read of size 4
==23949== at 0x40266A: GameWindow::get_pixel_color(SDL_Surface*, int, int) (GameWindow.cpp:174)
==23949== by 0x4022C3: GameWindow::draw_walls(SDL_Surface*, GameState*) (GameWindow.cpp:83)
==23949== by 0x402041: GameWindow::draw(SDL_Surface*, GameState*) (GameWindow.cpp:24)
==23949== by 0x404A16: Game::display_game_window() (Game.cpp:177)
==23949== by 0x404916: Game::game_loop() (Game.cpp:149)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== by 0x5CD313C: clone (in /usr/lib/libc-2.22.so)
==23949== Address 0x63b2a10 is 0 bytes after a block of size 96 alloc'd
==23949== at 0x4C2A987: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23949== by 0x4EDA0FF: ??? (in /usr/lib/libSDL2-2.0.so.0.2.1)
==23949== by 0x403800: Graphics::surface_copy(SDL_Surface*) (Graphics.cpp:80)
==23949== by 0x4035EC: Graphics::get_map(GID) (Graphics.cpp:31)
==23949== by 0x401FC8: GameWindow::GameWindow(Graphics*, GameState*) (GameWindow.cpp:15)
==23949== by 0x404511: Game::Game() (Game.cpp:47)
==23949== by 0x404C45: main (main.cpp:39)
==23949==
==23949== Use of uninitialised value of size 8
==23949== at 0x40444C: CollisionEngine::handle_wall_collision(GameState*, Character*) (CollisionEngine.cpp:155)
==23949== by 0x40404D: CollisionEngine::collision_check_player(GameState*) (CollisionEngine.cpp:39)
==23949== by 0x403F4C: CollisionEngine::collision_check(GameState*) (CollisionEngine.cpp:12)
==23949== by 0x404C1B: Game::advance_actual_state() (Game.cpp:276)
==23949== by 0x40490A: Game::game_loop() (Game.cpp:145)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== by 0x5CD313C: clone (in /usr/lib/libc-2.22.so)
==23949== Uninitialised value was created by a heap allocation
==23949== at 0x4C29118: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23949== by 0x404C3A: main (main.cpp:39)
==23949==
==23949== Invalid read of size 1
==23949== at 0x40444C: CollisionEngine::handle_wall_collision(GameState*, Character*) (CollisionEngine.cpp:155)
==23949== by 0x40404D: CollisionEngine::collision_check_player(GameState*) (CollisionEngine.cpp:39)
==23949== by 0x403F4C: CollisionEngine::collision_check(GameState*) (CollisionEngine.cpp:12)
==23949== by 0x404C1B: Game::advance_actual_state() (Game.cpp:276)
==23949== by 0x40490A: Game::game_loop() (Game.cpp:145)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== by 0x5CD313C: clone (in /usr/lib/libc-2.22.so)
==23949== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==23949==
==23949==
==23949== Process terminating with default action of signal 11 (SIGSEGV)
==23949== Access not within mapped region at address 0x0
==23949== at 0x40444C: CollisionEngine::handle_wall_collision(GameState*, Character*) (CollisionEngine.cpp:155)
==23949== by 0x40404D: CollisionEngine::collision_check_player(GameState*) (CollisionEngine.cpp:39)
==23949== by 0x403F4C: CollisionEngine::collision_check(GameState*) (CollisionEngine.cpp:12)
==23949== by 0x404C1B: Game::advance_actual_state() (Game.cpp:276)
==23949== by 0x40490A: Game::game_loop() (Game.cpp:145)
==23949== by 0x4067FC: void std::_Mem_fn_base<void (Game::*)(), true>::operator()<, void>(Game*) const (in /home/element/games/medieval_explorer/src/main)
==23949== by 0x40676A: void std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==23949== by 0x406684: std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)>::operator()() (functional:1520)
==23949== by 0x406623: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Game::*)()> (Game*)> >::_M_run() (thread:115)
==23949== by 0x540D34F: execute_native_thread_routine (thread.cc:84)
==23949== by 0x513E4A3: start_thread (in /usr/lib/libpthread-2.22.so)
==23949== by 0x5CD313C: clone (in /usr/lib/libc-2.22.so)
==23949== If you believe this happened as a result of a stack
==23949== overflow in your program's main thread (unlikely but
==23949== possible), you can try to increase the size of the
==23949== main thread stack using the --main-stacksize= flag.
==23949== The main thread stack size used in this run was 8388608.
==23949==
==23949== HEAP SUMMARY:
==23949== in use at exit: 52,118,160 bytes in 43,092 blocks
==23949== total heap usage: 111,139 allocs, 68,047 frees, 623,656,015 bytes allocated
==23949==
==23949== LEAK SUMMARY:
==23949== definitely lost: 16,911,956 bytes in 147 blocks
==23949== indirectly lost: 0 bytes in 0 blocks
==23949== possibly lost: 26,050,169 bytes in 41,710 blocks
==23949== still reachable: 9,156,035 bytes in 1,235 blocks
==23949== of which reachable via heuristic:
==23949== stdstring : 401 bytes in 6 blocks
==23949== suppressed: 0 bytes in 0 blocks
==23949== Rerun with --leak-check=full to see details of leaked memory
==23949==
==23949== For counts of detected and suppressed errors, rerun with: -v
==23949== ERROR SUMMARY: 351 errors from 5 contexts (suppressed: 0 from 0)
这是“handle_wall_collision”函数,其中代码采用段错误:
// character is in collision with walls, handle it
// only need to do one increment because the collision will be detected and handled again
void CollisionEngine::handle_wall_collision(GameState *game_state, Character *character){
// move a character the opposite direction of their speed until there is no more collision
// the until there is no more collision part is handled by the way this method is called
// we know how far they have moved into the object is some multiple of their speed
// get the sign of x_move_speed, y_move_speed
int x_sign = (character->map_location->x_move_speed == 0) ? (0) : (character->map_location->x_move_speed/abs(character->map_location->x_move_speed));
int y_sign = (character->map_location->y_move_speed == 0) ? (0) : (character->map_location->y_move_speed/abs(character->map_location->y_move_speed));
// determine the direction of movement
//if(abs(character->map_location->x_move_speed) > abs(character->map_location->y_move_speed)){
if(this->is_previous_collision_x){
character->map_location->x_location += -1*x_sign;
}else{
character->map_location->y_location += -1*y_sign;
}
//std::cout << "seg_fault_above" << std::flush;
}
注意,如果我避免使用任何成员变量(基本上任何可以被“this”引用的),那么代码工作正常。 我可以在构造函数中使用Member变量。
修改 成员this-&gt; is_previous_collision_x在构造函数中初始化:
CollisionEngine::CollisionEngine(){
this->is_previous_collision_x = false;
}
这是调用违规方法的循环:
// while there are collisions with the walls, handle them
do{
wall_collision = collision_check_wall(actual_state, actual_state->get_player());
if(wall_collision){
//std::cout << " wall collision detected\n";
handle_wall_collision(actual_state, actual_state->get_player());
}
}while(wall_collision);
我正在使用SDL2库。我已经确保使用这个库提供的方法来破坏我所做的纹理/表面/渲染,但是它们仍然会产生一些错误。
同样重要的是,玩家是一个角色。
修改 我感到异常愚蠢。 游戏持有* CollisionEngine作为私人成员 advance_actual_state()使用此指针调用collision_engine-&gt; collision_check(game_state)
问题是在构造函数中没有调用this-&gt; collision_engine = new CollisionEngine()。
答案 0 :(得分:1)
Access not within mapped region at address 0x0
注意0x0
那里?这意味着您尝试取消引用NULL指针。在代码中添加大量断言以尝试捕获它。例如,在函数入口点添加assert (this != NULL);
。
它也可以是character
或character->mmap_location
。为一切添加断言。
也许这会奏效:
void CollisionEngine::handle_wall_collision(GameState *game_state, Character *character){
if (this == NULL)
std::cerr << "CE:hwc, this is NULL" << std::endl;
if (character == NULL)
std::cerr << "CE:hwc character is NULL" << std::endl;
if (character->map_location == NULL)
std::cerr << "CE:hwc map_location is NULL" << std::Endl;
// rest of code here