【问题标题】:C++ Help about ZeroMemory关于 ZeroMemory 的 C++ 帮助
【发布时间】:2018-08-01 15:41:59
【问题描述】:

我像往常一样定义了我的 char,尽管我将它命名为 buf。我不断收到错误消息:

“char”类型的参数与“void*”类型的参数不兼容

如果我将buf设置为void*,它将无法将4096作为参数传入。

那么,我该如何解决这个问题?有没有人遇到过这样的问题?

    char buf{4096};
    string userinput;
    do
    {
        cout << "> " << endl;
        getline(cin, userinput);


        if (userinput.size() > 0) // make sure the user typed something in  
        {
            int SendResult = send(sock, userinput.c_str, userinput.size() + 1, 0);
            if (SendResult != SOCKET_ERROR)
            {
                ZeroMemory(buf, 4096);
                int bytesReceived = recv(sock, buf, 4096, 0);
                if (bytesReceived > 0)
                {
                    cout << "SERVER" << string(buf, 0, bytesReceived) << 
endl;
                }
            }
        }

【问题讨论】:

  • char buf{4096} 应该是char buf[4096]。您创建了一个字符缓冲区并尝试使用值 4096 填充它。
  • @tadman,可能是winapi function
  • @chris 很好。 SendResult 命名约定让我大吃一惊。
  • char buf{4096} 声明了一个char,其值为4096。你想要char buf[4096]
  • @MilesBudnek 并不是说​​ 4096 将永远适合具有 8 位字符的“无聊”平台...buf 可能是 0 几乎所有这些。

标签: c++ winapi char


【解决方案1】:

使用字符 buf[4096]; 代替 buf{4096} 使用 buf 作为数组,然后用零填充内存块

顺便说一句,你真的知道 buf{4096} 是做什么的吗? 如果你这样做,这意味着你想把这个数字 4096 它将被转换为“(`”,因为buf数据类型是char所以你使用了错误的方式。

ZeroMemory(buf, 4096);    
// Wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
    {
        cerr << "Error in recv(). Quitting" << endl;
        break;
}

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

另一个问题是你为什么需要ZeroMemory。而且我认为这里发生的事情是您选择了错误的字符串构造函数重载。让我解释一下:

你有你的buf 缓冲区和你的bytesReceived 数据长度,所以你真正需要的是

std::string(buf, bytesReceived)

构造有效的字符串。但是你选择了

std::string(buf, 0, bytesReceived)

这个重载看起来像这样:

basic_string( const basic_string& 其他, size_type 位置, size_type 计数, ..

buf 在第一个参数处被隐式转换为std::string,但要使其正常工作,您的缓冲区需要以空值终止,它可能会也可能不会。因此,您通过将缓冲区的其余部分归零来解决此问题。如果你得到 4096 字节的非空终止数据,你认为会发生什么?在这种情况下,您的解决方法将不起作用。所以只需使用上面提到的适当的字符串构造函数,就不需要使用ZeroMemory

【讨论】:

  • 根据 Remy Lebeau 的说法,我们必须回答具体问题,而不是提供更好的选择。是的……我知道。
  • 是的。您的回答很好,但显然是题外话。这与我在下面被否决的原因相同。我只是在说明一点:)。
  • @Robinson 好吧,我要赞成你的回答,我希望你对此感到非常难过,你这个小家伙
  • 我并不难过。
【解决方案3】:

怎么样:

#include <array>   

std::array<char, 4096> buf;
...    

        std::fill(buf.begin(), buf.end(), 0);
        int bytesReceived = recv(sock, buf.data(), buff.size(), 0);
...

【讨论】:

  • 当然,这是一种更好的方法,但这并不能回答实际提出的问题。 StackOverflow 是一个问答网站,我们是来回答问题的,而不是重写代码。
  • 问题是,“那么,我该如何解决这个问题?”。在我看来,答案涉及到 std::array 的使用。不,我们不只是来回答这个问题。如果我们是,我们就不会投票反对这么多。这也是一个 C++ 问题。我的回答是惯用的 c 样式数组。
  • 所问的问题是关于修复错误消息,而不是更改代码的语义。这就是Code Review 的用途。
【解决方案4】:

问题很可能是这个定义:

char buf{4096};

大致相当于:

char buf = 4096;

这是单个字符,而不是字符数组缓冲区。要解决这个问题:

char buf[4096];

当传递它时,你可能需要这样做:

ZeroMemory(&buf, 4096);

我强烈建议您避免在任何地方敲出 4096,因此定义一个常量:

const SIZE_T buf_size = 4096;
char buf[buf_size];

// ...

ZeroMemory(&buf, buf_size);

【讨论】:

  • 请注意,由于大括号变窄,符合标准的 C++11 编译器不会编译它。 (并且 C++11 之前的编译器无法识别初始化的形式。)我认为 4096 在 Windows 上不是有效的 char 值是一个公平的假设。
  • 随便ZeroMemory(&amp;buf, sizeof buf);
  • 由于buf 是一个固定数组,传递它的名字与传递一个指向它的第一个元素的指针是一样的,所以你根本不需要&amp;ZeroMemory(buf, sizeof(buf)); On另一方面,在本例中,在调用recv() 之前根本不需要将buf 归零,这只是浪费开销。
猜你喜欢
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多