У меня есть буфер чтения двоичного файла, который читает структуры переменной длины. В конце буфера всегда будет неполная структура. Я хочу переместить такой конец буфера в его начало, а затем прочитать buffer_size - tail_len
байт во время следующего чтения файла. Как то так:
char[8192] buf;
cur = 0, rcur = 0;
while(1){
read("file", &buf[rcur], 8192-rcur);
while (cur + sizeof(mystruct) < 8192){
mystruct_ptr = &buf[cur];
if (mystruct_prt->tailsize + cur >= 8192) break; //incomplete
//do stuff
cur += sizeof(mystruct) + mystruct_ptr->tailsize;
}
memcpy(buf,&buf[cur],8192-cur);
rcur=8192-cur;
cur = 0;
}
Это должно быть в порядке, если хвост маленький, а буфер большой, потому что тогда memcpy
скорее всего не будет перекрывать скопированный сегмент памяти во время итерации одной копии. Однако это звучит немного рискованно, когда хвост становится большим - больше 50% буфера.
Если буфер действительно велик, а tail тоже огромен, тогда все равно должно быть в порядке, поскольку существует физический предел того, сколько данных может быть скопировано за одну операцию, которое, если я правильно помню, составляет 512 байт для современных процессоров x86_64, использующих векторные блоки. Я думал о добавлении условия, которое проверяет длину хвоста и, если оно слишком велико по сравнению с размером буфера, выполняет наивное побайтовое копирование, но вопрос таков:
Насколько большой слишком большой, чтобы считать такое перекрытие memcpy
более или менее безопасным. tail > buffer size - 2kb