You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

游戏开发返回主方法时出现'Terminate called without an active exception'错误求助

Hey there! Let's figure out why you're hitting that "Terminate called without an active exception" error and get your game's respawn loop working right.

What's Causing the Error?

Your code has two critical issues that lead to this crash:

  1. Unmanaged Thread Lifecycle: In first::func(), you create a std::thread called getDirection, but you never call join() or detach() on it before func() returns. When the thread object goes out of scope (when func() ends), C++ requires that joinable threads are either joined or detached—if not, the program calls std::terminate() to avoid resource leaks, which is exactly the error you're seeing.
  2. Dangling Object Access: When main() finishes a loop iteration, the first object f gets destroyed. But your getDir() thread is still running and trying to access this->ch (a member of the now-destroyed object). This is undefined behavior—it might crash immediately, cause weird glitches, or seem to work randomly.

Fixes to Get Your Respawn Loop Working

We need to fix both the thread management and object safety issues. Here are two solid solutions tailored to your game's respawn flow:

Solution 1: Use a Thread-Safe Flag to Stop and Join the Thread

This is the safest approach—we'll add a flag to tell the input thread to exit, then wait for it to finish before returning to main() for a new game round.

#include<iostream>
#include<conio.h>
#include<thread>
#include<atomic>
#include<chrono> // For sleep_for to reduce CPU usage
using namespace std;

class first{
public:
    int ch;
    atomic<bool> is_running; // Thread-safe flag to control the input thread
    void getDir();
    void func();
};

void first::getDir(){
    while(is_running){
        // Check if a key is pressed first to avoid blocking on _getch()
        if(_kbhit()){
            ch = _getch();
        }
        // Add a small delay to keep CPU usage low
        this_thread::sleep_for(chrono::milliseconds(10));
    }
}

void first::func(){
    is_running = true; // Start with the flag enabled
    thread getDirection(&first::getDir, this);
    
    while(1){
        // Your game logic here
        while(1){
            // Your inner loop logic (e.g., checking for player death)
            // When you need to respawn (return to main):
            is_running = false; // Tell the input thread to exit
            getDirection.join(); // Wait for the thread to fully stop
            return;
        }
    }
}

int main(){
    while(1){
        first f;
        f.func();
        // At this point, f's thread has already joined, so no dangling access
    }
}

Key Changes Explained:

  • atomic<bool> is_running: Uses an atomic type to ensure the flag is read/written safely across threads (no race conditions).
  • _kbhit() check: Prevents _getch() from blocking indefinitely, so the input thread can quickly respond when is_running is set to false.
  • getDirection.join(): Waits for the input thread to finish before func() returns, ensuring the thread object is no longer joinable when it's destroyed.

Solution 2: Detach the Thread (Less Ideal for Your Respawn Flow)

If you wanted the input thread to run independently, you could use detach(), but this requires ensuring the first object doesn't get destroyed while the thread is running. Since your main() loop creates a new first object each round, this approach is risky—you'd have to manage object lifetimes carefully (e.g., using dynamic allocation). For your respawn use case, Solution 1 is far more reliable.

Quick Best Practices for Game Threading

  • Always manage thread lifetimes explicitly—never leave a joinable thread unjoined/unattached.
  • Avoid forcing threads to terminate (there's no standard C++ way to do this safely). Use flags like we did to let threads exit gracefully.
  • Keep input threads lightweight to avoid hogging CPU cycles (the small sleep_for in our fix helps with this).

内容的提问来源于stack exchange,提问作者Nnnnn

火山引擎 最新活动