Violação de acesso ao local de leitura e erro ao ler o caractere da sequência

Quem pode explicar por que o erro de localização de leitura de violação de acesso é acionado e por que em [] eu recebo "caracteres de leitura de string errorr"? Eu tenho duas strings e devo remover todas as palavras da primeira string que contenham outra string. O que eu faço de errado?

#include "stdafx.h"
#include<iostream>
#include<cstring>
using namespace std;
char s1[100] = {};
char s2[100] = {};
void Words(char s1[], char s2[]) {
  int k = 0;
  char*p1 = nullptr;
  char*np1 = nullptr;
  char*p2 = nullptr;
  char*np2 = nullptr;
  char *m[20];
  char *a[20];
  char s3[100] = {};
  for (int i = 0; i < 20; i++) {
    char n[50] = {};
    char l[50] = {};
    m[i] = n;
    a[i] = l;

  }
  char delimeter[] = " ,.!?;:";
  p2 = strtok_s(s2, delimeter, &np2);
  while (p2 != nullptr) {
    strcpy(a[k], p2);
    k++;
    p2 = strtok_s(nullptr, delimeter, &np2);
  }
  k = 0;
  p1 = strtok_s(s1, delimeter, &np1);
  while (p1 != nullptr) {
    strcpy(m[k], p1);
    k++;
    p1 = strtok_s(nullptr, delimeter, &np1);
  }

  for (int i = 0; i < 20; i++) {
    for (int j = 0; j < 20; j++) {
      if (strcmp(m[i], a[j]) != 0 && m[i] != 0 && a[j] != 0) {
        strcat(s3, m[i]);
      }
    }
  }
  puts(s3);
  for (int i = 0; i < 20; i++) {
    delete m[i];
    delete a[i];
  }
}

Função principal:

int main()
{
  gets_s(s1);
  gets_s(s2);
  Words(s1, s2);
  return 0;
}

questionAnswers(2)

yourAnswerToTheQuestion