对char数组的访问冲突

Qix*_*Qix 0 c++ arrays strcmp access-violation

我在创建的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;
        }
Run Code Online (Sandbox Code Playgroud)

_lpCommands是一个Command结构数组:

struct Command
{
    char* szCommand;
    CommandCallback cbCallback;
};
Run Code Online (Sandbox Code Playgroud)

生成的错误消息是:

Program.exe中0x012219cf处的未处理异常:0xC0000005:访问冲突写入位置0x66647366.

这是对使用的类似代码的重写memcmp,最终给了我一个访问冲突,而不是做了memcpy.

是什么赋予了?

era*_*ran 6

不要传递&cmdblipmemcpy.您应该将指针传递给目标缓冲区,而不是指向该指针的指针.通过cmdblip代替.

编辑:我同意一般来说,std :: string应该在C++中使用.此代码崩溃的技术原因仍然是memcpy破坏cmdblip指针,使其指向实际由复制字符串的前4个字节组成的内存位置.然后,cmdblip[len]导致内存位置不在分配的缓冲区(或任何其他合法分配的缓冲区)内,因此崩溃.因此,如果您想编写更好的代码,请使用C++类.如果您想了解给定代码崩溃的原因,请考虑以上内容.

  • @DeadMG,请将鼠标放在你点击的那个小向下箭头上.它应该弹出一条消息:"这个答案没用".我的答案肯定是有用的 - 它解决了有问题的问题.如果你想成为一个纯粹主义者,你就可以按自己的想法表达自己的想法.不要滥用downvoting - 这个答案是完全正确的,即使它没有改变OP对C++编程的一般方法. (4认同)
  • 是的,在此期间,将`cmdStr`参数的类型更改为`const char*`.您没有在代码中修改该字符串,因此请保护自己免受将来的意外修改. (2认同)

Pup*_*ppy 5

这个问题唯一可能有用的答案是"使用std::string".您现在遇到的具体问题只会在每次修改此函数或写入其他类似函数时重新出现或相同.在一般情况下解决问题的唯一方法是转向基于类的解决方案,这是一种为您提供标准的解决方案.例如,您的当前代码是异常不安全的,除了提供访问冲突的任何内容之外,更不用说它是不可读的并且要求许多其他错误,例如一个一个错误,没有正确的NULL终止,双删除和内存泄漏.哦,和UB,因为你delete是你new[].