Search code examples
cstringmultidimensional-arraysegmentation-faultdynamic-arrays

C: 2-Dimensional String Array Segmentation Fault


Trying to make a small program that separates words within a big string and stores each word (of the big string) in a string (i.e pointer) in an array of strings (i.e pointers); forming a 2-dimensional string array. The word separator is simply a whitespace (32 in ASCII); the big string is:


"Showbizzes Oxygenized Equalizing Liquidized Jaywalking"

Note:

  • the words are all 10 characters in length
  • the total length of the string is 54 characters (spaces included)
  • the total size of the buffer is 55 bytes ('\0' included)

One more thing, the last pointer in the array of pointers must hold a 0 (i.e 1 character: '\0') (this is completely arbitrary).


Here is the program, nothing special, but ...

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

int main(void) {

    // The string that we need to break down into individual words
    char str[] = "Showbizzes Oxygenized Equalizing Liquidized Jaywalking";

    // Allocate memory for 6 char pointers (i.e 6 strings) (5 of which will contain words)
    // the last one will just hold 0 ('\0')
    char **array; array = malloc(sizeof(char *) * 6);

    // i: index for where we are in 'str'
    // r: index for rows of array
    // c: index for columns of array
    int i, r, c;

    // Allocate 10 + 1 bytes for each pointer in the array of pointers (i.e array of strings)
    // +1 for the '\0' character
    for (i = 0; i < 6; i++)
        array[i] = malloc(sizeof(char)*11);

    // Until we reach the end of the big string (i.e until str[i] == '\0');
    for (i = 0, c = 0, r = 0; str[i]; i++) {

        // Word seperator is a whitespace: ' ' (32 in ASCII)
        if (str[i] == ' ') { 

            array[c][r] = '\0';     // cut/end the current word
            r++;                    // go to next row (i.e pointer)
            c = 0;                  // reset index of column/letter in word
        }

        // Copy character from 'str', increment index of column/letter in word
        else { array[c][r] = str[i]; c++; }

    }   

    // cut/end the last word (which is the current word)
    array[c][r] = '\0'; 

    // go to next row (i.e pointer)
    r++; 

    // point it to 0 ('\0')
    array[r] = 0; 



// Print the array of strings in a grid - - - - - - - - - - - - - - 

    printf("       ---------------------------------------\n"); 
    for (r = 0; r < 6; r++) {

        printf("Word %i --> ", r);
        for (c = 0; array[c][r]; c++)
            printf("| %c ", array[c][r]);

        printf("|");printf("\n");
        printf("       ---------------------------------------");
        printf("\n");
    }

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    return 0;
}

.. there's something wrong and I don't understand how to fix it.


For some reason it copies into the first string (i.e pointer), in the array of strings (i.e pointers), the first 6 characters of the big string, then on the 7th it gives a segmentation fault. I've allocated 6 pointers each with 11 bytes.. at least thats what I think the code is doing, so really I have NO clue why this is happening...

Hope someone can help.


Solution

  • Replace all ocurrences of array[c][r] with array[r][c]

    The first dimension is the row.

    Next time you can check this using a debugger:

    Program received signal SIGSEGV, Segmentation fault.
    0x00000000004007ea in main () at demo.c:37
    37  array[c][r] = str[i];