简体   繁体   中英

C++ Copy Raw std::bytes to std::vector<std::byte>

I have an FILE_NOTIFY_INFORMATION struct which i have filled like this:

FILE_NOTIFY_INFORMATION* fni = new FILE_NOTIFY_INFORMATION;
fni->Action = 1;
wcscpy_s(fni->FileName,12, L"example.txt");
fni->FileNameLength = 12;
fni->NextEntryOffset = 0;

I have then castet this Struct to an std::byte* .

auto fni_as_byte = reinterpret_cast<std::byte*>(fni);

Now i want to put this fni_as_byte into an vector of std::vector<std::byte> . Because i need this for testing purpose.

Normally you receive the FILE_NOTIFY_INFORMATION for example from the ReadDirectoryChangesW function. And it's called like this:

std::vector<std::byte> notifyBuffer(1024);
res = ReadDirectoryChangesW(handle, notifyBuffer.data(), static_cast<DWORD>(notifyBuffer.size()), false, FILE_NOTIFY_CHANGE_FILE_NAME, nullptr, &overlapped, nullptr);

So how can i manually copy the castet FILE_NOTIFY_INFORMATION into the std::vector<std::byte> ?

Your code is corrupting memory, as the actual size of FILE_NOTIFY_INFORMATION is variable length. SeeWhy do some structures end with an array of size 1? . You are not allocating enough memory to hold the string you are copying into the FileName . To allocate your FILE_NOTIFY_INFORMATION correctly , you would need to do something more like this instead:

FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*) new std::byte[offsetof(FILE_NOTIFY_INFORMATION, FileName[12])];
fni->Action = 1;
wcscpy_s(fni->FileName, 12, L"example.txt");
fni->FileNameLength = 11 * sizeof(WCHAR); // <— expressed in BYTEs, not including the null terminator!
fni->NextEntryOffset = 0;
...
delete (std::byte*) fni;

That being said, to copy the FILE_NOTIFY_INFORMATION into a std::vector , you can do it like this:

FILE_NOTIFY_INFORMATION* fni = ...;
// fill fni as needed...
std::vector<std::byte> buffer(offsetof(FILE_NOTIFY_INFORMATION, FileName) + fni->FileNameLength);
std::memcpy(buffer.data(), fni, buffer.size());
// use buffer as needed...

Alternatively, just use the std::vector up front as the memory for the original FILE_NOTIFY_INFORMATION :

std::vector<std::byte> buffer(offsetof(FILE_NOTIFY_INFORMATION, FileName[12]));
auto fni = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(buffer.data());
// fill fni as needed....
// use buffer as needed...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM