How can I serialize a cudaIpcMemHandle_t?

I’m trying to open cudaIpcMemHandle_t structs that have been serialized to std::string (really, just a way to move the bytes around), and I can’t get it to work.

Here’s a code sample that illustrates the problem. The first loop opens the handles w/o issue. The second loop, which deserializes the handles from std::string returns “invalid argument”:

    std::vector<std::string> handles(world_size);
    handles.reserve(world_size);
    for (int i = 0; i < world_size; ++i) {
      // convert *begin 
      char *begin = (char *)(&rank_handles[i]);
      char *end1 = (char *)(&rank_handles[i + 1]);
      std::string handle_str(begin, end1);
      handles.push_back(handle_str);
    }

    {
      for (int i = 0; i < world_size; ++i) {
        if (i == world_rank) continue; // skip self (otherwise we get an 'invalid context' error)
        cudaIpcMemHandle_t handle = rank_handles[i];
        char* ptr;
        CUDACHECK(cudaIpcOpenMemHandle((void **)&ptr, handle, cudaIpcMemLazyEnablePeerAccess));
        printf("Rank %d: opened handle %d before registration\n", world_rank, i);
      }
    }

    {
      for (int i = 0; i < world_size; ++i) {
        if (i == world_rank) continue; // skip self (otherwise we get an 'invalid context' error)

        // open the string handle
        char* ptr;
        CUDACHECK(cudaIpcOpenMemHandle((void **)&ptr, *(const cudaIpcMemHandle_t *)handles[i].data(), cudaIpcMemLazyEnablePeerAccess));
        printf("Rank %d: opened handle %d before registration (v2)\n", world_rank, i);
      }
    }

Update serializing the handles with:

      char buffer[sizeof(cudaIpcMemHandle_t)];
      memcpy(buffer, &rank_handles[i], sizeof(cudaIpcMemHandle_t));
      handles[i] = std::string(buffer, sizeof(cudaIpcMemHandle_t));

fixed the issue. But, I’m not sure why.