# Thread: Help -- allocating memory in a multidimensional array

1. ## Help -- allocating memory in a multidimensional array

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];
}
}
}
}```

2. Code:
`data[t][numOf[t]-i] = malloc(sizeof(char)*strlen(data[t][numOf[t]-i-1]));`
Are you sure this last subscript cannot = -1 the first time?

• when you are trying to work out a syntax problem, don't bother doing it in the the main body of your code. It's too easy to end up with a steadily increasing headache.
• use a lot of printf(); fflush(stdout); to debug

The solution to #1 is to set the code aside and try to write as short a program as you can that still encapsulates the issue. That will help to "encapsulate the issue", which is paramount. It will also free you from believing you have something right (or wrong) when you have only done it once. If you encapsulate (refine, focus, whatever) and come up with a few slight variations, this will clarify the syntax/methodology in your mind AND you have a much greater chance than if you just manage to pull it off once in your project, it which case "luck" would be a bad thing.

Also, by writing abstract examples for yourself (eg, passing a 3D pointer array around) you will build up a collection of easy to consult abstract examples that you wrote.

3. Ya I put printf() everywhere, I only deleted them all when I posted to the forum, that's how I know exactly where it was breaking.

And the index should never be -1, because if numOf[t] is 0 it does the above loop, otherwise it comes into this loop, which means numOf[t] >= 1, so it started at numOf[t] - i - 1, which is 1 - 0 - 1 = 0.

I've worked through all the algorithms a hundred times, I don't know what I'm missing.

4. strlen does not include the null terminator in its size count.

Quzah.

5. Okay so I added a +1 to the end of all my malloc() calls (inside the parenthesis of course). Still get a Segmentation fault at the same place.

Also, should I be "free()" ing anything up? I'm not quite sure where I would put that in this case.

6. so I noticed I have this code:
Code:
```int i;
for (i = 0; i < numOf[t]-n; i++);
{
printf("i is %i, n is %i, numOf[%i] is %i\n", i, n, t, numOf[t]);```
and on the FIRST iteration, 'i' is 1. Why is that? I set it to 0, so why is it 1??

7. A link to my entire .c file is func.c

8. This is the perfect case for a debugger. If it supports your platform, I recommend Valgrind. It's great. Otherwise find out what debuggers are available (gdb probably runs all sorts of places) and give one a shot. But Valgrind really should be the first choice.

I will tell you that you should store the return value of fgetc() into an int, not a char. Depending on whether char is unsigned or signed, you'll either never see EOF or a valid character will look like EOF.

9. Originally Posted by jonathan.plumb
so I noticed I have this code:
Code:
```int i;
for (i = 0; i < numOf[t]-n; i++);
{
printf("i is %i, n is %i, numOf[%i] is %i\n", i, n, t, numOf[t]);```
and on the FIRST iteration, 'i' is 1. Why is that? I set it to 0, so why is it 1??
I think you believe your print statement is inside your for loop. It is not.

10. In case you still haven't caught onto what tabstop is saying:
Code:
```for (i = 0; i < numOf[t]-n; i++);
{```

Quzah.

11. Yeah, your increaseArray() is way off.

Conceptually, all you need is
Code:
`data[list] = malloc( sizeof(char*) * (numOf[list] + 1) );`
That is, having done
data[0] = malloc( sizeof(char*) );
you can then do
data[0][0] = malloc( strlen(s) + 1 ); and then copy your string.

The second thing you're doing wrong (conceptually) in this function is recopying all the actual strings. You have an array of pointers to strings. You can quickly "copy" a string just by copying the pointer.

So you should be doing
- make a new array which is one pointer bigger than last time
- copy all the existing pointers
- free the old array of pointers (it's now too small anyway, and you've copied all you need)

Hint: realloc() does ALL that for you