对char数组的访问冲突

时间:2012-06-27 18:28:06

标签: c++ access-violation strcmp arrays

我使用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:Access   违规写作地点0x66647366。

这是对使用memcmp的类似代码的重写,最终在不执行memcpy的情况下给我一个访问冲突。

是什么给出了?

2 个答案:

答案 0 :(得分:6)

不要将&cmdblip传递给memcpy。您应该将指针传递给目标缓冲区,而不是指向该指针的指针。改为通过cmdblip

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

答案 1 :(得分:5)

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