I need some help with allocating memory. This is for a school assignment and the notes I've taken in class aren't quite helping me solve the problem.

Basically I have a list of words and I make sentences from those words. I've drawn a '-->>' next to the part of the code that is causing a segmentation fault. Please help me understand why.

I have the following variables:
Code:
char **data[4];
int numOf[] = {0,0,0,0};
and here is my insane function that is giving me a segmentation fault
Code:
void addWord(char *type, char *word)
{
	// compare() just returns a 1 if the word matches, or a 0 if not
	int t = compare(type, "article")?0:compare(type, "noun")?1:compare(type, "verb")?2:3;

	// This method dynamically increases the size of my array. The code is below
	increaseArray(t);
	int n = 0;
	// If there's nothing there ... add something there
	if (numOf[t] == 0)
	{
		data[t][0] = malloc(sizeof(char)*strlen(word));
		strcpy(data[t][0], word); 
		numOf[t]++;
		printLists();
		return;
	}
	// Otherwise add in sorted order
	else
	{
		for (n = 0; n < numOf[t]; n++)
		{
			// compareTo() returns a -1 if it's less than, 1 if greater than, or 0 if equal
			// like in java
			if (compareTo(word, data[t][n]) < 0)
			{
				int i;
				for (i = 0; i < numOf[t]-n; i++);
				{
					// So this is what's breaking ... I allocate memory at the end of my
					// list equal to the size of the item 1 from the end, then I copy the item
					// from 1 from the end into the end, rinse and repeat down the list
					// backwards.  However it breaks on the first attempt to move a word
-->>					data[t][numOf[t]-i] = malloc(sizeof(char)*strlen(data[t][numOf[t]-i-1]));
					strcpy(data[t][numOf[t]-i], data[t][numOf[t]-i-1]);
				}
				data[t][n] = malloc(sizeof(char)*strlen(word));
				strcpy(data[t][n], word);
				numOf[t]++;
				printLists();
				return;
			}
			// If our word already exists....just ignore it
			else if (compareTo(word, data[t][n]) == 0) { printLists(); return; }
		}
		// If we've gone through the list and not added it by now, then
		// it is obviously going to go to the end of the list...so let's
		// allocate memory and put it in!
		strcpy(data[t][n], word);
		numOf[t]++;
		printLists();
		return;
	}
}

// Here is my method for increasing my array dynamically. This may be part of my 
// problem, and I'm sure there's an easier way.
void increaseArray(int list)
{
	auto char **tempArray[4];
	tempArray[0] = malloc(numOf[0]);
	tempArray[1] = malloc(numOf[1]);
	tempArray[2] = malloc(numOf[2]);
	tempArray[3] = malloc(numOf[3]);

	int x = 0, y = 0, z = 0;
	for (x = 0; x < 4; x++)
	{
		for (y = 0; y < numOf[x]; y++)
		{
			tempArray[x][y] = malloc(sizeof(char)*strlen(data[x][y]));
			for (z = 0; z < strlen(data[x][y]); z++)
			{
				tempArray[x][y][z] = data[x][y][z];
			}
		}
	}

	data[list] = malloc(numOf[list]+1);

	for (x = 0; x < 4; x++)
	{
		for (y = 0; y < numOf[x]; y++)
		{
			data[x][y] = malloc(sizeof(char)*strlen(tempArray[x][y]));
			for (z = 0; z < strlen(tempArray[x][y]); z++)
			{
				data[x][y][z] = tempArray[x][y][z];
			}
		}
	}
}