(long long int*) calloc(len_s1, sizeof(int));
вы выделяете массив int на len_s1 элементов, а потом работаете с ним, как с массивом long long той же длины. Но long long занимает больше байт! Поэтому вы выделяете меньше памяти, чем используете, а это UB. Почему возникает free(): double free detected
String
копия получает то же значение str
что и оригинал с которого она скопирована, в деструкторе копия удаляет str
оригинала, а потом это же делает оригинал в своём деструкторе. См. правило трёх/пяти.