Указание размера аргумента массива не имеет никакого эффекта.
void func(char b[SIZE]);
эквивалентно
void func(char *b);
Следовательно, когда вы говорите
case 1: *(p+n)=(char *)malloc(sizeof(b));
sizeof будет соответствовать размеру указателя на char. Попробуйте использовать
case 1: *(p+n)=(char *)malloc(SIZE * sizeof(b));
Та же ошибка возникает, когда вы говорите
*(p+n)=(char *)malloc(sizeof(b));
Который вы можете изменить на
*(p+n)=(char *)malloc(SIZE * sizeof(b));
Вы должны установить размер так, чтобы в буфере было место для всей строки, включая символ новой строки, а также завершающий символ \ 0. В противном случае strcpy не будет работать правильно. Вы должны использовать strncopy в любом случае. После того, как вы внесете эти изменения, fgets вернет 0, когда будет достигнут конец файла, и ваша программа сообщит «Ошибка при чтении файла!». Вы должны соответствующим образом изменить завершение цикла чтения.
Кроме того, вы на самом деле не используете многомерный массив. Вы используете массив указателей на массивы символов. В C 2-мерный массив будет размещен в непрерывном блоке памяти и доступен в основном порядке строк. Это было бы хорошо в вашем случае, потому что все строки должны иметь одинаковую длину. Тем не менее, вы пытаетесь поддерживать массив указателей, которые в свою очередь указывают на строки. Это также работает, но технически это не то, что мы бы назвали многомерным массивом в C. Он называется вектор Iliffe или просто массив .
В целом, ваш код довольно запутан и труден для понимания. Вам следует попытаться упростить вашу программу, которая в будущем значительно облегчит вам поиск ошибок.