This program separates palindromes from non-palindromes in a text file. After separating them into separate two dimensional arrays, I have to sort them in ascending order by string length. The last part is to output both the palindromes and non-palindromes in centered, triangle format. I've gone through this program multiple times and I can't seem to find what's causing it.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 512

void format(char **list, int count){

	int longestLine = strlen(list[count-1]);

        int i, j, k, numOfSpaces, flag;

        for(i = 0; i < count; i++){

                int len = strlen(list[i]);

                if(((longestLine - len) % 2) == 0){
                        numOfSpaces = ((longestLine - len) / 2);
                }
                else{
                        numOfSpaces = ((longestLine - len - 1) / 2);
                        flag = 1;
                }

                for(j = 0; j < numOfSpaces; j++){
                        printf(" ");
                }

                printf("%s", list[i]);

                if(flag == 1){
                        for(k = 0; k < (numOfSpaces + 1); k++){
                                printf(" ");
                        }
                }
                else{
                        for(k = 0; k < numOfSpaces; k++){
                                printf(" ");
                        }
                }

                printf("\n");

        }

	printf("\n");
}

void swap(char * line1, char * line2){

	char tmp[MAX];

	strcpy(tmp, line1);
	strcpy(line1, line2);
	strcpy(line2, tmp);

}

void lower(char * line){

	int len = strlen(line);
	int i;

	for(i = 0; i < len; i++){
		if((line[i] >= 'A') && (line[i] <= 'Z')){
			line[i] = line[i] + 32; //ASCII uppercase to lowercase is a difference of 32
		}
	}
	
}

void removeSpaces(char * line, char * newLine){

	int len = strlen(line);
	int i;
	int newCount = 0;

	for(i = 0; i < len; i++){
		if((line[i] >= 'a') && (line[i] <= 'z')){
			newLine[newCount] = line[i];
			newCount++;
		}
	}

}

int isPalin(char * line){

	char tmp1[MAX];
	char tmp2[MAX];
	strcpy(tmp1, line);

	lower(tmp1);
	removeSpaces(tmp1, tmp2);

	int last = strlen(tmp2) - 1;
	int first = 0;

	while(first < last){

		if(tmp2[first] != tmp2[last]){
			return 0;
		}
		
		first++;
		last--;
	}

	return 1;
	
}

int main(){

	char lines[MAX][MAX];
	char palindromes[MAX][MAX];
	char notPalin[MAX][MAX];	
	
	int n = 0;
	int i;
	int palinCount = 0;
	int noPalinCount = 0;

	while(gets(lines[n]) != NULL){

		if(strcmp(lines[n], "END") == 0){
			break;
		}

		n++;
	}

	for(i = 0; i < n; i++){
		if(isPalin(lines[i])){

			strcpy(palindromes[palinCount], lines[i]);
			palinCount++;

		}

		else{

			strcpy(notPalin[noPalinCount], lines[i]);
			noPalinCount++;
	
		}
	}

	//SORT PALINDROME ARRAY

	int swapped = 1;
	int j;

	while(swapped){
	
		swapped = 0;
	
		for(j = 0; j < palinCount - 1; j++){

			if(strlen(palindromes[j]) > strlen(palindromes[j+1])){

				swap(palindromes[j], palindromes[j+1]);
				swapped = 1;
		
			}
		
		}

	}

	//SORT NON-PALINDROME ARRAY

	swapped = 1;
	
	while(swapped){

		swapped = 0;

		for(j = 0; j < noPalinCount - 1; j++){

			if(strlen(notPalin[j]) > strlen(notPalin[j+1])){

				swap(notPalin[j], notPalin[j+1]);
				swapped = 1;
		
			}

		}
	
	}

	printf("\n");
	printf("\n");

	//PRINT FORMATTING

	format((char **)palindromes, palinCount);

	format((char **)notPalin, noPalinCount);
				

	return 0;
}

I just learned how to use gdb and it looks like this line in format() is causing the segfault. I'm still not sure why, though.

int longestLine = strlen(list[count-1]);

Good for you. Gdb is a way to go.

Your problem is that you equate a 2-dimensional array to a double indirection. They are different creatures. That's why the compiler warned you, so that you ended up with explicit cast on lines 197 and 199.

When your function sees a char ** list , it expects (loosely speaking) an array of pointers: list[x] must be a pointer. Of course it is not, because the original array does not contain any. With its declaration in scope (that is knowing the row width), the compiler is able to figure out where each row starts.
In a format function this information is lost.
A solution, instead of fooling the compiler with casts, is to declare your true intentions:

void format(char lines[][MAX], count)

and happily get rid of casts.

This question has already been answered. Start a new discussion instead.