首页 > 解决方案 > 未处理的异常:将无效参数传递给服务或函数但仅在程序完成后

问题描述

根据分配,我创建了一个子类(PioneerWorld),它公开PioneerAm继承自PioneerCarRadio,继承自,继承自基类CarRadio

然后我调用了一个函数,该函数新建了适当的类对象并将指针返回到一个PioneerCarRadio * pRadio指针。

程序然后循环,然后用户可以选择在 、 或 之间PioneerCarRadio更改PioneerAm收音机PioneerWorld。选择不同的收音机会删除之前的对象,pRadio并使用前面提到的功能通知适当的收音机。

出现的问题是,在我选择切换到然后退出程序后的任何时候,Unhandled 异常:PioneerWorld

A-06.exe 中 0x7765806C (ntdll.dll) 处的未处理异常:0xC000000D:向服务或函数传递了无效参数。发生了

会发生在return 0for main之后。即使该程序不在 PioneerWorld 电台上时正在退出。

它不会对任何其他收音机执行此操作,只有在节目期间的任何时间选择 PioneerWorld 时才会发生这种情况。

据我所知,问题出在PioneerWorld.h文件中。

我试图在 try 块中添加每一种异常捕获(当然,我不相信我对 try-catch 异常处理的工作原理有深入的了解),但没有一个能够解决问题。

我已经在调试模式下运行它并且一切运行顺利,直到:

   printf("\nGoodbye!\n");
   return 0;
}  **<-- HERE**

我试图将 PioneerWorld 放在继承层次结构的更高位置(例如,而不是

CarRadio-> PioneerCarRadio-> PioneerAm-> PioneerWorld

我把它改成

CarRadio-> PioneerCarRadio-> PioneerWorld-> PioneerAm

而且同样的问题仍然存在。(在 pRadio 切换到 PioneerWorld 电台后随时退出会导致错误,但如果电台从未切换到 PioneerWorld则不会发生错误)

老实说,我不知所措。;_;

主要的:

#include <stdio.h>
#include <string.h>
#include <new.h>
#include <exception>
#include <conio.h>
#include "PioneerWorld.h"
#include <iostream>
#pragma warning(disable :4996)
using namespace std;

//Prototype
PioneerCarRadio * createRadio(char *s);

int main(int argc, char * argv[])
{
    //Variables
    PioneerCarRadio * pRadio = NULL;
    char *arg = argv[argc - 1];
    char previousArg[8] = "";
    char selection = 0;

    //Loops the main process
    do
    {
        //Checks if the previous argument is the same as the current, if not then create a new radio
        if (strcmp(previousArg, arg) != 0)
        {
            //Creates the radio and reads any exceptions thrown
            try
            {
                pRadio = createRadio(arg);
                strcpy(previousArg, arg);
            }
            catch (char* e)     //If argument is not present or invalid, exception is caught here
            {
                printf("\n EXCEPTION: Invalid switch modifier.\n");
                return -1;
            }
            catch (bad_alloc& ba)   //If no memory can be allocated in the instantiation of the radio, exception is caught here
            {
                printf("\n EXCEPTION: Cannot allocate memory.\n");
                return -2;
            }
            catch (bad_exception& e)            //Catch exceptions for unknown errors
            {
                printf("\n EXCEPTION: Unknown Excpetion Error.\n");
                return -3;
            }
            catch (runtime_error& re)
            {
                printf("\n EXCEPTION: Runtime error\n");
                return -4;
            }
        }

        //Shows the currents settings for radio
        pRadio->ShowCurrentSettings();

        //Gets the user inputed selection
        selection = pRadio->GetInput();

        //Make the selection setting change (if appilicable)
        pRadio->MakeSelection(selection);

        //Redisplay the settings in case they had been adjusted
        pRadio->ShowCurrentSettings();

        //Checks what selection was made and changes the argument to the appropriate syntax
        if (selection == 'c')
        {
            strcpy(arg, "-car");
        }
        else if (selection == 'a')
        {
            strcpy(arg, "-am");
        }
        else if (selection == 'w')
        {
            strcpy(arg, "-world");
        }

        //Checks if the previous argument is the same as the current, if not then delete the current object
        if (strcmp(previousArg, arg) != 0 || selection == 'x')
        {
            //Deletes the current object 
            try
            {
                delete pRadio;
            }
            catch (bad_exception& e)        //Catches any unexpected exceptions
            {
                printf("\n EXCEPTION: Unknown Exception\n");
                return -5;
            }
            catch (runtime_error& re)
            {
                printf("\n EXCEPTION: Runtime error\n");
                return -6;
            }
        }


    } while (selection != 'x');     //Exits when user selects 'x'

    printf("\nGoodbye!\n");
    return 0;
}

PioneerCarRadio * createRadio(char *s)
{
    //Variables
    PioneerCarRadio * returnPtr = NULL;

    //Check if the parameter is there and valid
    if (s == NULL)
    {
        throw s;    //throw the parameter
    }
    else if (strcmp(s, "-car") == 0)
    {
        //News the PioneerCarRadio and throws the pointer if NULL
        if ((returnPtr = new PioneerCarRadio(false)) == NULL)
        {
            throw returnPtr;
        }
        else
        {
            return returnPtr;
        }
    }
    else if (strcmp(s, "-am") == 0)
    {
        //News the PioneerAM and throws the pointer if NULL
        if ((returnPtr = new PioneerAM(false)) == NULL)
        {
            throw returnPtr;
        }
        else
        {
            return returnPtr;
        }
    }
    else if (strcmp(s, "-world") == 0)
    {
        //News the PioneerWorld and throws the pointer if NULL
        if ((returnPtr = new PioneerWorld(false)) == NULL)
        {
            throw returnPtr;
        }
        else
        {
            return returnPtr;
        }
    }
    else
    {
        throw s;
    }

    return NULL;    //Default return

}

问题儿童(PioneerWorld.h文件):

#include <stdio.h>
#include"PioneerAM.h"


//Class
class PioneerWorld : public PioneerAM
{
private:

public:
    PioneerWorld(bool power, char *name = (char *)"Pioneer XS440-WLRD") : PioneerAM(power, name)
    {
        ChangeCurrentStation(531);
    }

    virtual ~PioneerWorld()
    {
        printf("Destroying Pioneer XS440-WRLD Radio.\n");
    }

    virtual void ScanUp()
    {
        Freqs storedAM = GetStoredFreqs();

        //if current_station is 1700, the current_station becomes 530
        if (GetCurrentStation() >= 1602)
        {
            ChangeCurrentStation(531);
            storedAM.AMFreq = GetCurrentStation();
        }
        else
        {
            ChangeCurrentStation(GetCurrentStation() + 9);
            storedAM.AMFreq = GetCurrentStation();
        }
    }

    virtual void ScanDown()
    {
        Freqs storedAM = GetStoredFreqs();

        //if current_station is 1700, the current_station becomes 530
        if (GetCurrentStation() <= 531)
        {
            ChangeCurrentStation(1602);
            storedAM.AMFreq = GetCurrentStation();
        }
        else
        {
            ChangeCurrentStation(GetCurrentStation() - 9);
            storedAM.AMFreq = GetCurrentStation();
        }
    }
};

程序应该一直运行,直到它没有错误地终止并捕获任何异常,但是如果在收音机切换到 PioneerWorld 收音机后的任何时候退出程序,程序将正常执行,直到主程序返回 0;此时,在下一行('}')上,视觉工作室出现了一个错误:

A-06.exe 中 0x7765806C (ntdll.dll) 处的未处理异常:0xC000000D:向服务或函数传递了无效参数。发生了

这是我的第一篇文章,所以如果有任何问题或者您想要更多代码以更好地了解问题所在,请询问。

谢谢您的帮助!

标签: c++exceptiontry-catch

解决方案


推荐阅读