char *s = new char[strlen(source) + 1];
...
strcpy_s(s, strlen(s), source);
strlen(s)
-- вообще за гранью добра и зла и возвращает случайное число, по большому счёту. Потому что s -- только что выделенный неинициализированный массив.
Вызов
strcpy_s
совершенно бессмысленный и неправильный. Бессмысленный, потому что ты только что выделил столько памяти, сколько данных в строке. strcpy_s имеет смысл, если буфер в который ты копируешь -- это массив фиксированной длины. Неправильный, потому что даже если ты имел в виду
strlen(source)
, а не
strlen(s)
, то должен был передать
strlen(source) + 1
, чтобы было куда 0-терминатор скопировать. Кроме всего прочего, strcpy_s ещё и возвращает код ошибки, который имеет смысл проверить.
Лучше всего в этом месте было бы вызвать
memcpy(s, source, strlen(source) + 1);
или вообще выкинуть
s = new char [...]; strcpy_s ... delete [] s;
и заменить на
s = strdup(source); ... free(s);
Если очень хочется strcpy_s, то хотя бы так:
strcpy_s(s, strlen(source) + 1, source);
Исправление этого места починит и delete, потому что delete валится из-за того, что ты поломал heap.