【问题标题】:How to get the values of a std::vector<int>*?如何获取 std::vector<int>* 的值?
【发布时间】:2021-09-12 22:01:04
【问题描述】:

我不知道在“标题”框中输入什么内容,因此我认为该标题没有完全回答我的问题,对此我深表歉意。

首先,我想提供一些背景信息。我发现网络为 3D 游戏开发了两周。

今天我专注于使用std::vector.obj 发送模板来运送包裹,但这不是我的问题。

问题是我没有收到来自这个向量的信息。

由于一张图片值一千字,这是我的代码(这段代码只是为了测试'服务器'端的char[]中的数据加密和客户端的接收)。

我的 C++ 程序:

#include <vector>
#include <iostream>

int main()
{
    /* -- server -- */
    // variables to buffer
    std::vector<int> vec = { 1, 25, 156, 0, 1 };
    short type = 25;
    int written = 0;
    char buffer[256] = {};

    memcpy(&buffer[written], &type, sizeof(type));
    written += sizeof(type);

    memcpy(&buffer[written], &vec, sizeof(vec));
    written += sizeof(vec);

    std::cout << "/* -- Server -- */\n" << std::endl;
    std::cout << "[written] --> " << "Size : " << sizeof(written) << " | Value : " << written << std::endl;
    std::cout << "[type] --> " << "Size : " << sizeof(type) << " | Value : " << type << std::endl;
    std::cout << "[vec] --> " << "Size : " << sizeof(vec) << " | Value : " << vec.data() << std::endl;

    // 'send' to client && 'receive' from server \\ (for example)
    char buffer2[256] = {};
    memcpy(&buffer2, &buffer[0], sizeof(buffer2));

    /* -- client -- */
    // buffer to variables
    std::vector<int>* vec2;
    short type2 = 0;
    int read = 0;
    
    memcpy(&type2, &buffer[read], sizeof(type2));
    read += sizeof(type2);

    memcpy(&vec2, &buffer[read], sizeof(vec2));
    read += sizeof(vec2);

    std::cout << "\n\n";
    std::cout << "/* -- Client -- */\n" << std::endl;
    std::cout << "[read] --> " << "Size : " << sizeof(read) << " | Value : " << read << std::endl;
    std::cout << "[type2] --> " << "Size : " << sizeof(type2) << " | Value : " << type2 << std::endl;
    std::cout << "[vec2] --> " << "Size : " << sizeof(vec2) << " | Value : " << vec2->data() << std::endl;


    std::cout << "\n"; system("pause");
    return 0;
}

cmd的返回:

/* -- Server -- */

[written] --> Size : 4 | Value : 18
[type] --> Size : 2 | Value : 25
[vec] --> Size : 16 | Value : 00589A00

/* -- Client -- */

[read] --> Size : 4 | Value : 6
[type2] --> Size : 2 | Value : 25
[vec2] --> Size : 4 | Value : 00000000

Press any key to continue...

【问题讨论】:

  • std::vector 不是一个简单的可复制类型。 memcpy它是没有意义的。如果您打算 memcpy 底层元素数组,则需要 memcpy data() 返回的指针。
  • 我恐怕不明白,这种情况下我应该用什么代替memcpy来给字符数组加值呢?

标签: c++ networking game-development


【解决方案1】:
memcpy(&buffer[written], &vec, sizeof(vec));

你已经在这里遇到了问题,甚至在收到任何东西之前。

sizeof(vec)std::vector&lt;int&gt; 的大小。这可能是 8 或 16 个字节,或类似的东西。向量的大小将始终相同,无论向量是空的,还是包含百科全书中每一页的图像。

向量和向量中的内容是两个完全不同的东西。

一个向量的size()方法给出了向量中值的个数,所以上面显然应该是:

    memcpy(&buffer[written], vec.data(), vec.size()*sizeof(int));

其余代码应作相应调整。

同样,反序列化成向量的过程也是错误的,如下所示:

    std::vector<int>* vec2;

这是一个指向向量的指针。在 C++ 中,在使用指针之前,必须将其初始化为指向相同类型的现有实例。显示的代码中没有任何内容可以做到这一点。

    memcpy(&vec2, &buffer[read], sizeof(vec2));

由于vec2 是一个指针,sizeof(vec2) 将是一个指针的大小:4 或 8 个字节。这试图反序列化指针的原始内存地址。同样,这没有任何意义。

显示的代码试图做的应该是:

  1. 声明你的向量

     std::vector<int> vec2;
    
  2. 确定将多少个值读入向量,并调整其大小。例如,如果您知道要反序列化 n 字节的原始整数数据:

     vec2.resize(n / sizeof(int));
    

此时您可以将原始数据复制到 epointer 中。

    memcpy(vec2.data(), &buffer[written], n);

由于调整大小,这种方法效率稍低,但这是次要问题。也可以以对 C++ 更友好的方式实现此逻辑,但这也是次要问题。主要问题是您的sizeof 不会神奇地为您提供将被读入向量的字节数。这是您需要自己跟踪的内容。 C++ 能为你做的很少,你总是需要做所有的工作。您需要弄清楚如何跟踪实际读取的字节数,这些字节构成了向量的内容,然后相应地调整大小并读入向量。

【讨论】:

  • 感谢他的解释和建议,我看到我有很多空白要填补,但我会重新编写代码。按照您的建议尝试,再次感谢您
  • @The_ChaosStar 如果此答案有帮助,您可能应该对其进行投票以表明其质量。如果它回答了问题并且发布了最佳答案,您也应该考虑接受它(绿色复选标记)。
  • 原来我之前关于.data() 的评论并不完全准确。 memcpy 不幸的是 UB 如果任一指​​针是 nullptr 即使 size 为 0。我仍然更喜欢 data() 但如果 size 为 0 则无济于事。
猜你喜欢
  • 2015-09-20
  • 1970-01-01
  • 2020-01-26
  • 2017-02-01
  • 1970-01-01
  • 2017-04-16
  • 2018-12-13
  • 2017-05-13
  • 1970-01-01
相关资源
最近更新 更多