Благодаря г-ну Стиву Вишновски из команды MSFT VC ++, здесь приведено полное объяснение проблемы.
Wcscpy_s не работает атомарно на буферах и будет работать правильно только если буферы не работаютизменить содержимое во время выполнения wcscpy_s.
Еще одна вещь, на которую следует обратить внимание, это то, что в режиме отладки функция wcscpy_s заполнит оставшуюся часть буфера отладочной меткой (0xFE), чтобы указать, что данные там сейчаснедопустимо предполагать, что это содержимое, чтобы обнаружить потенциальные ошибки времени выполнения.
Ошибка возникает каждый раз по-разному, но давайте предположим, что эта ошибка происходит, когда вызывается src = 1269.9 и вызывается wcscpy_s (dst, src). Фактическое содержимое src: «1 2 6 9. 9 null 0xfe 0xfe ...». wcscpy_s копирует 1269.9, но когда он собирается прочитать нулевое значение, другие wcscpy_s просто записали новое значение в src, и теперь оно выглядит так: «1 2 7 0 null 0xfe 0xfe ...». Вместо чтения нулевого значения, соответствующего предыдущему src, он читает 0xfe, поэтому думает, что это настоящий символ. Так как нулевой терминатор отсутствует до тех пор, пока мы не достигнем конца буфера, среда выполнения Debug утверждает, что буфер был слишком мал для ввода.
В сборке Release отладочные метки 0xFE не помещаются вбуфер, поэтому он в конечном итоге найдет нулевой символ. Вы также можете отключить отметки отладки, вызвав _CrtSetDebugFillThreshold: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetdebugfillthreshold?view=vs-2019.
Обратите внимание, что отметки отладки фактически улавливают проблему реальной корректности. Эта проблема «буфер изменен во время wcscpy_s» может возникнуть при любом значении. Например, если src = 1269.9, wcscpy_s может скопировать 126, но затем, когда он собирается прочитать 9, src обновляется до 1270, и значение, которое в конечном итоге будет в dest, будет равно «1260».