How to get the values of a std::vector<int>*?

Viewed 177

I do not know what to put in the 'Title' box so I consider that the title does not completely answer my problem and I am sorry about it.

First of all, I would like to give a bit of context. I discovered the development of the network for two weeks now for a 3D game.

Today I'm focusing on shipping packages using std::vector to send templates as .obj, but that's not my problem.

The problem is that I am not receiving the information from this vector.

As a picture is worth a thousand words, here is my code (this code is just to test the encryption of the data in a char[] on the 'server' side and the reception on the client side).

My C++ program:

#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;
}

Return of the 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...
1 Answers
memcpy(&buffer[written], &vec, sizeof(vec));

You already have problems here, even before receiving anything.

sizeof(vec) is the size of std::vector<int>. Which will probably be 8 or 16 bytes, or something like this. The size of the vector will always be the same, whether the vector is empty, or holds an image of every page in an encyclopedia.

A vector, and what's in a vector, are two completely different things.

A vector's size() method gives the number of values in the vector, so the above should obviously be:

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

The rest of the code should be adjusted accordingly.

Similarly, the process of deserializing into a vector is also wrong, in the shown code:

    std::vector<int>* vec2;

This is a pointer to a vector. In C++, before using a pointer it must be initialized to point to an existing instance of the same type. There's nothing in the shown code that does that.

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

Since vec2 is a pointer, sizeof(vec2) will be the size of a pointer: either 4 or 8 bytes. This attempts to deserialize the raw memory address of a pointer. Again, this makes no sense.

What the shown code is attempting to do should be:

  1. Declare your vector

     std::vector<int> vec2;
    
  2. Determine how many values will be read into the vector, and resize it. If, for example, you know that you have n bytes worth of raw integer data to deserialize:

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

At this point you can copy the raw data into th epointer.

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

This approach is slightly inefficient, due to resizing, but that's a secondary issue. It's also possible to implement this logic in more C++-friendly ways, but that's also a secondary issue. The main issue is that your sizeof will not magically give you the number of bytes that will be read into a vector. This is something that you need to track by yourself. There's very little that C++ will do for you, you'll always have to do all the work. You need to figure out how to keep track of the actual number of bytes that were read, that comprise the contents of the vector, then resize and read into the vector, accordingly.

Related