Thread: Sorting 3D matrix (Segmentation Fault)

  1. #1
    C <3er
    Join Date
    Jul 2011
    Posts
    46

    Exclamation Sorting 3D matrix (Segmentation Fault)

    Hi! New problems come to me... the problem seems simple the solution... well can't seem to find it now and since people here seem very nice and helpy here it goes

    I have a struct which is table it has a cell member which is a pointer to a pointer to a pointer of chars in other words a 3 dimensional dynamic array of chars... I use this as a table container so it is like a 2 dimensional array of strings. I tried writing a simple function to sort the table using the bubble sort algorithm to order (this is important) just the first column and starting on the second row (since the first row is reserved for the column header and shouldn't be sorted)
    But at some point I'm getting a segmentation fault (programming under codeblocks 10.05 and gcc on windows I get a SIGSEV msg) lately I've been reading about this trying to find the problem... like NULL pointers and that kind of things but I don't seem to find what going wrong... here is the sorting function, I'm not sure if it is the problem so if you need some code about the table and the create_table routine I'm using etc... tell me!

    Code:
    void sort_table(table *t){
        int i, j, order;
        table tmp;
        tmp = create_table("tmp", t->rows, t->cols);
    
        i = 1;
        order = 0;
        while(order == 0){
            for(j = 1; j < t->rows - i + 1; ++j){
                order = 1;
                if(strcmp(t->cell[j][0], t->cell[j+1][0]) > 0){
                    tmp.cell[j] = t->cell[j];
                    t->cell[j] = t->cell[j+1];
                    t->cell[j+1] = tmp.cell[j];
                    order = 0;
                }
            }
            ++i;
        }
    }
    Thank you very much in advance!!

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Compile in debug mode and run it in the debugger.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Have you run the code in the debugger (after compiling with -g option).

    The debugger will catch the segfault and point you directly at the line of code causing the problem.

    From there, it is up to you.

    Without all the type declarations, and how your code constructed the table(s) to begin with, we don't really have any idea where to start looking.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Yeah... of course, I have already done that but the only message I receive is segmentation fault, and I don't seem to find a null pointer anywhere... if I try to run a modified function which only sorts the first to rows it works the problems seems to come when I introduce the loop... The line it marks is the strcmp one, but I have no idea why... I'll post the "constructor" of the table and the struct as to see if it helps someone:
    Code:
    typedef struct{
        int rows, cols;
        unsigned long int id;
        char *name;
        char ***cell; // 3d array of chars or 2D array of strings
    }table;
    Code:
    /* create_table: create a table with given rows and columns and return it */
    table create_table(char *name, int rows, int cols){
        int i, j;
        static unsigned long int id;
        table t;
    
        clip(&rows, 1, TABLE_MAX_ROWS);
        clip(&cols, 1, TABLE_MAX_COLS);
    
        t.rows = rows;
        t.cols = cols;
    
        t.cell = (char ***) malloc(rows * sizeof(char **));
    
        if(t.cell == NULL){
            printf("\n\t\tERROR: Out of memory\n");
            printf("\n\t\tPress any key to exit...\n");
            getchar();
            exit(EXIT_FAILURE);
        }
    
        for(i = 0; i < rows; ++i){
            t.cell[i] = (char **) malloc(cols * sizeof(char *));
            if(t.cell[i] == NULL){
                printf("\n\t\tERROR: Out of memory\n");
                printf("\n\t\tPress any key to exit...\n");
                getchar();
                exit(EXIT_FAILURE);
            }
            for (j = 0; j < cols; j++){
                t.cell[i][j] = (char *)malloc(NAME_MAX_LEN * sizeof(char));
                if(t.cell[i][j] == NULL){
                    printf("\n\t\tERROR: Out of memory\n");
                    printf("\n\t\tPress any key to exit...\n");
                    getchar();
                    exit(EXIT_FAILURE);
                }
            }
        }
    
        t.name = name;
        t.id = id++;
    
        return t;
    }
    Then the table is assigned when needed like:
    Code:
    table t;
    t = create_table(...);
    There's of course another function to delete the table when the program exists or the table is closed :P

    P.S: I know it's not easy for me neither to show you were to start looking so all the info you need ask me please :P
    Also I wanted to know first if the sort_table function looks right or if there's something wrong with it because I'm getting so confused
    Last edited by beta3designs; 07-31-2011 at 09:59 AM.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by beta3designs View Post
    Hi! New problems come to me... the problem seems simple the solution... well can't seem to find it now and since people here seem very nice and helpy here it goes

    I have a struct which is table it has a cell member which is a pointer to a pointer to a pointer of chars in other words a 3 dimensional dynamic array of chars... I use this as a table container so it is like a 2 dimensional array of strings. I tried writing a simple function to sort the table using the bubble sort algorithm to order (this is important) just the first column and starting on the second row (since the first row is reserved for the column header and shouldn't be sorted)
    But at some point I'm getting a segmentation fault (programming under codeblocks 10.05 and gcc on windows I get a SIGSEV msg) lately I've been reading about this trying to find the problem... like NULL pointers and that kind of things but I don't seem to find what going wrong... here is the sorting function, I'm not sure if it is the problem so if you need some code about the table and the create_table routine I'm using etc... tell me!

    Code:
    void sort_table(table *t){
        int i, j, order;
        table tmp;
        tmp = create_table("tmp", t->rows, t->cols);
    
        i = 1;
        order = 0;
        while(order == 0){
            for(j = 1; j < t->rows - i + 1; ++j){
                order = 1;
                if(strcmp(t->cell[j][0], t->cell[j+1][0]) > 0){
                    tmp.cell[j] = t->cell[j];
                    t->cell[j] = t->cell[j+1];
                    t->cell[j+1] = tmp.cell[j];
                    order = 0;
                }
            }
            ++i;
        }
    }
    Thank you very much in advance!!
    Let me guess... it sorts column 0 but disconnectes it from column[i] in the process....

    This is the fun part about 2d or 3d matrixes... if you want to keep the rows intact you have to shuffle the entire row, not just the first column.

    Most likely the seg-fualt is because your t->cell array magically became a 1 dimensional array when sorting.

  6. #6
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Yeah I want to shuffle the entire row sorry about not saying that! xD
    How should I go about that commontater? Thanks a lot!! And thanks in advance!

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If it's complaining about strcmp, that means that t->cell[j+1][0] is NULL (or just points somewhere in New Jersey). How you got such a thing in there.....

    EDIT: Also:
    Code:
    tmp = create_table("tmp", t->rows, t->cols);
    Aaaaaaaaaaah! Don't create another entire table just to do the swapping of some rows! Just make tmp a char**, since that's what you are swapping.
    Last edited by tabstop; 07-31-2011 at 11:04 AM.

  8. #8
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Thanks for the swapping thing tabstop, i know the problem might be that t->cell[j+1][0] = NULL but it shouldn't happen to be like that... I'll wait for commontater to see if he can point me in the right direction with suffling the entire row and what I'm doing wrong... :S

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You are shuffling the entire row.

  10. #10
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Then...
    Most likely the seg-fualt is because your t->cell array magically became a 1 dimensional array when sorting.
    Is this incorrect or what? I mean, I was trying to shuffle the entire row but as CommonTater said this I thought some code might be wrong...
    Then what should I do next? I think the dynamic memory is allocated correctly, as far as I know the only thing I can think about is that my allocation of memory is not contiguous but I didn't consider this necessary is it? Mmm I don't know which info do you need to help me out? My project is composed of many files so it is hard to post and reading the code is time consuming for everyone, but I really need to get this segmentation fault tracked down

    The project consists in creating, reading and modifying tables is some kind of simple database, when you create a table the create_table function is called and the table is written to a file and then you are given a menu where you can manipulate the table. If you close the table or modify it it is written again. You can also open a table and then the table is read from the file with a function whose body can be sortened to this so you can get the idea:
    Code:
    t = create_table(name, rows, cols);
    
        i = j = k = 0;
        while(fscanf(fin, "%c", &ch) != EOF){
            if(ch == '\t'){
                t.cell[i][j][k] = '\0';
                k = 0;
                ++j;
            }else if(ch == '\n'){
                t.cell[i][j][k] = '\0';
                k = 0;
                j = 0;
                ++i;
            }else{
                t.cell[i][j][k] = ch;
                ++k;
            }
            t.cell[i][j][k] = '\0';
        }
    return t;
    The program seems to create, open and read tables correctly and I haven't had any problems until this :S
    Last edited by beta3designs; 07-31-2011 at 12:32 PM.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by beta3designs View Post
    Yeah I want to shuffle the entire row sorry about not saying that! xD
    How should I go about that commontater? Thanks a lot!! And thanks in advance!
    Once you know which rows need to be exchanged... just move the whole row in a loop...

    One trick, although it's a bit more code... Make your "index row" (0?) a separate array of structs with pointers to the rows in the other array. That way you only have to sort the index without disturbing the pointers.

  12. #12
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Well tabstop says that my code already shuffles the entire row and that's what I was tryin to accomplish by using:
    Code:
    tmp.cell[j] = t->cell[j];
    t->cell[j] = t->cell[j+1];
    t->cell[j+1] = tmp.cell[j];
    Doesn't this copy the entire row?

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    All those things are pointers, so you're just swapping pointers to the row. You just have to turn "tmp.cell[j]" into something meaningful and not go over the line and/or figure out how you are getting NULL pointers.

  14. #14
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Sorry can you elaborate more on this I don't understand what you are trying to say, I don't get what's turning tmp.cell[j] into something meaningful mean I'm pretty lost :S

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Something you can actually use to swap, as in make it a char** and lose the [j] and the .cell.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault?
    By Camambert in forum C++ Programming
    Replies: 2
    Last Post: 08-20-2009, 11:21 AM
  2. Pointer to a matrix - Segmentation fault
    By endomlic in forum C Programming
    Replies: 2
    Last Post: 04-10-2009, 12:24 AM
  3. Segmentation Fault :(
    By DarkDot in forum C++ Programming
    Replies: 39
    Last Post: 04-07-2007, 04:16 AM
  4. segmentation fault : matrix multiplication ??
    By gemini_shooter in forum C Programming
    Replies: 11
    Last Post: 06-24-2005, 09:50 AM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM

Tags for this Thread