0

を使用して作成しchar配列でアクセス違反が発生しnewます。

DispatchCommand(char* cmdStr)
        {
            // Dispatch
            for(int i = 0; i < sizeof(_lpCommands); i++)
            {
                const int len = strlen(_lpCommands[i].szCommand);
                char* cmdblip = new char[len + 1];
                memcpy(&cmdblip, cmdStr, len);
                cmdblip[len] = '\0';  // Access Violation

                if(strcmp(cmdblip, _lpCommands[i].szCommand) == 0)
                {
                    if(strlen(cmdStr) > strlen(_lpCommands[i].szCommand))
                        (*_lpCommands[i].cbCallback)(&cmdStr[strlen(_lpCommands[i].szCommand)]);
                    else
                        (*_lpCommands[i].cbCallback)("");

                    delete cmdblip;
                    return;
                }

                delete cmdblip;
            }

            // Error and return
            *Out::ServerInfo<<"Command not found!"<<ENDL;
        }

_lpCommandsは、Command構造体の配列です。

struct Command
{
    char* szCommand;
    CommandCallback cbCallback;
};

生成されるエラーメッセージは次のとおりです。

Program.exeの0x012219cfで未処理の例外:0xC0000005:アクセス違反の書き込み場所0x66647366。

これは、を使用していた同様のコードの書き直しでありmemcmp、結果として、を実行せずにアクセス違反も発生しましたmemcpy

何が得られますか?

4

2 に答える 2

6

に渡さないで&cmdblipくださいmemcpy。そのポインタへのポインタではなく、宛先バッファへのポインタを渡す必要があります。代わりに合格cmdblipします。

編集:一般的に、std::stringはC++で使用する必要があることに同意します。それでも、このコードがクラッシュする技術的な理由はmemcpy、ポインタが破損しcmdblip、コピーされた文字列の最初の4バイトで実際に作成されているメモリ位置を指すようになるためです。次に、cmdblip[len]割り当てられたバッファ(または他の合法的に割り当てられたバッファ)内にないメモリ位置が発生するため、クラッシュします。したがって、より良いコードを記述したい場合は、C++クラスを使用してください。また、特定のコードがクラッシュした理由を理解したい場合は、上記を検討してください。

于 2012-06-27T18:31:28.430 に答える
5

この質問に対する唯一の可能な有用な答えは「使用std::string」です。現在発生している特定の問題は、この関数を変更したり、別の関数を記述したりするたびに、単に再発するか、同じ問題になります。一般的なケースで問題を解決する唯一の方法は、標準として提供されているクラスベースのソリューションに移行することです。たとえば、現在のコードは例外的に安全ではありません。アクセス違反を引き起こしていることに加えて、読み取り不能であり、1つずつ正しくない、適切にNULLで終了していない、doubleなど、他の多くのエラーを要求していることは言うまでもありません。削除し、メモリリークが発生します。ああ、そしてUBはあなたがdelete何をしているのかnew[]

于 2012-06-27T18:39:55.193 に答える