简体   繁体   中英

C++ program crashing on Python script call

I am attempting to send a command that runs a specific python script: however, whenever the program reaches the execution line, this occurs:

Unhandled exception at 0x69bd1f16 in GameServer.exe: 0xC0000005: Access violation reading location 0x46f520ca.

The program stops resonding and crashes. Here is the method in question:

void ScriptManager::runScript(std::string scriptName, std::string args[])
{
    std::string py = "python " + scriptName;
    std::cout << py << std::endl;
    for(int i = 0; i < args->length(); i++)
    {
        py += " " + args[i];
        std::cout << py << std::endl;
    }
    std::cout << py << std::endl;

    std::system(py.c_str());

}

This calls the above function:

void DBFactory::dbRegisterUser(std::string username, std::string password)
{
    ScriptManager script;
    std::string data[] = {username, password};

    script.runScript("Python.py", data);
}

The script does not run, as far as I know. I can also post the script if it would help.

This is the problem:

for (int i = 0; i < args->length(); i++)
{
    py += " " + args[i];
    std::cout << py << std::endl;
}

args->length() is equivalent to args[0].length() ; ie you're taking the length of the first string in the array and using that as an index. After two iterations pass, you're going to access past the end of the array. The best solutions are(all examples are UNTESTED):

  1. Use an std::array (C++11 only):

     void DBFactory::dbRegisterUser(std::string username, std::string password) { ScriptManager script; script.runScript("Python.py", {username, password}); } void ScriptManager::runScript(std::string scriptName, std::array<std::string, 2> args) { std::string py = "python " + scriptName; std::cout << py << std::endl; for (std::string s : args) { py += " " + s; std::cout << py << std::endl; } std::cout << py << std::endl; std::system(py.c_str()); } 
  2. Use an std::vector (the example uses C++03):

     void DBFactory::dbRegisterUser(std::string username, std::string password) { ScriptManager script; int tmp[2] = {username, password}; script.runScript("Python.py", std::vector<std::string>(&tmp[0], &tmp[0]+2)); } void ScriptManager::runScript(std::string scriptName, std::vector<std::string> args) { std::string py = "python " + scriptName; std::cout << py << std::endl; for(std::vector<std::string>::iterator it = args.begin(); it != args.end(); it++) { py += " " + *it; std::cout << py << std::endl; } std::cout << py << std::endl; std::system(py.c_str()); } 
  3. Pass the array size as a parameter:

     void DBFactory::dbRegisterUser(std::string username, std::string password) { ScriptManager script; script.runScript("Python.py", {username, password}, 2); } void ScriptManager::runScript(std::string scriptName, std::string args[], int size) { std::string py = "python " + scriptName; std::cout << py << std::endl; for(int i=0; i<size; i++) { py += " " + args[i]; std::cout << py << std::endl; } std::cout << py << std::endl; std::system(py.c_str()); } 

I personally prefer example 1 and would avoid example 3 like the plague. Example 2 works well but probably isn't as fast as example 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM