【问题标题】:how do I solve this C++ access violation problem?如何解决这个 C++ 访问冲突问题?
【发布时间】:2019-12-04 07:53:15
【问题描述】:

我在以下代码中遇到错误。写入 _buf 时,Visual Studio 会引发访问冲突错误。我该如何解决这个问题?

Sendn 函数是一个套接字发送函数。这不是问题,你可以忽略它。

看起来_buf 指向0x00000000

我看到的错误信息是

0xC0000005: 0x00000000 : access violation
void ?????::?????(int number, string title)
{

    int titlesize = sizeof(title);
    int bufsize = 4 + 4 + 4 + titlesize;

    char *_buf = new char[bufsize];

    _buf = { 0 };

    // char _buf[bufsize] = { 0 }; (수정 내용)

    int commands = 3;

    int index = 0;
    memcpy(_buf, &commands, sizeof(int));
    index += sizeof(int);

    memcpy(_buf + index, &number, sizeof(int));
    index += sizeof(int);

    memcpy(_buf + index, &titlesize, sizeof(int));
    index += sizeof(int);
    for (int i = 0; i < titlesize; i++)
    {
        memcpy(_buf + index, &title[i], sizeof(char));
        index += sizeof(char);
    }

    Sendn(_buf, bufsize);

    delete[] _buf;

    return;
}

【问题讨论】:

  • 你是什么原因memcpy()-ing title,一次一个字符,有自己专用的for 循环,而不是简单地memcpy()ing 整个事情,一口气?
  • 旁注,虽然我认为这不是问题,但作为一般规则,starting symbol names with an underscore is a bad idea 因为如果操作不当,可能会导致意外使用一些保留的标识符。
  • 其他注意事项:您可能应该执行int bufsize = sizeof(int) + sizeof(int) + sizeof(int) + titlesize; 之类的操作,而不是int bufsize = 4 + 4 + 4 + titlesize;,因为int is not guaranteed to be 4 bytes
  • 我建议使用std::copy 而不是memcpy,因为它更安全且同样快速。

标签: c++


【解决方案1】:

您正在尝试将title 的内容与其他3 个整数一起复制到_buf 中,对吗?问题是sizeof(title) 不是存储在title 中的字符串的长度。为了得到title的长度,你需要像这样在std::string类型上调用成员函数length

auto titlesize = title.length();

sizeof 运算符只为您提供std::string 对象在堆栈上的大小(相比之下,实际字符串存储在堆上),sizeof 表达式始终是常量表达式。在我的电脑上,sizeof(std::string) 是 24,无论实际字符串是什么。

【讨论】:

  • 顺便说一下,std::string::lengthstd::string::size 的行为完全相同。
【解决方案2】:
char *_buf = new char[bufsize];
_buf = { 0 };

这不会对_buf 指向的动态分配数组进行零填充。它将指针_buf 设置为空指针。由于_buf 是一个空指针,以后尝试取消引用它会导致未定义的行为。

在这种情况下,不需要对_buf 指向的数组进行零填充,因此您可以简单地删除_buf = { 0 }; 行。


一旦你解决了这个问题,你也没有分配正确的内存量。 sizeof(title) 不会给你title 持有的字符数。它只是为您提供std::string 对象的静态大小,通常只有一个指针和两个整数。请改用title.size()

【讨论】:

  • 有趣的是,std::fill() 将填充这样的数组。
猜你喜欢
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多