Help with array/pointer segmentation fault needed

Discussion in 'C Programming' started by Ben, Jun 9, 2006.

  1. Ben

    Ben Guest

    Hi,

    I am having trouble debugging a segmentation fault...here's my data structure:

    typedef struct CELL *pCELL; /* Pointers to cells */
    struct CELL {
    SYMBOL symbol;
    pCELL prev_in_block;
    pCELL next_in_block;
    pCELL prev_in_column;
    pCELL next_in_column;
    pCELL prev_in_row;
    pCELL next_in_row;
    };
    pCELL mArray[MAX2][MAX][MAX][MAX2]; /* The multi-dimensional array */


    So, mArray is an array of pointers to CELLs. And each CELL contains a symbol and pointers to the neighbouring CELLs. I am
    representing a 4d "grid" here, but you can think of it like a 2d one.

    Note the boundary CELLS should not point to anything, e.g. the first piece in a row should have a prev_in_block value of NULL,
    meaning the address of the CELL it points to is NULL, meaning there's no such CELL.

    Ok, my problem comes when trying to ACCESS symbols via the pointers, e.g. printing out the symbol in a "square" in the grid and
    all of it's surrounding symbols. Then I get an intermittent seg fault. This first line is always ok:

    value = mArray[bb][cc][rr][vv]->symbol;

    But one or more of the following will cause a seg fault:

    pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;


    I can't find a particular pattern with this, different "squares" (changing bb,cc etc) crash it at different lines - it seems to
    be no relation to which squares have a NULL pointer for example.

    But, some of the statements above work correctly some of the time...leading me to believe I have the syntax correct. So what
    could be the issue? If there's any other information needed happy to provide.

    cheers,

    Ben
     
    Ben, Jun 9, 2006
    #1
    1. Advertising

  2. Ben

    Ben Guest

    Ben wrote:
    > Hi,
    >
    > I am having trouble debugging a segmentation fault...here's my data
    > structure:
    >
    > typedef struct CELL *pCELL; /* Pointers to cells */
    > struct CELL {
    > SYMBOL symbol;
    > pCELL prev_in_block;
    > pCELL next_in_block;
    > pCELL prev_in_column;
    > pCELL next_in_column;
    > pCELL prev_in_row;
    > pCELL next_in_row;
    > };
    > pCELL mArray[MAX2][MAX][MAX][MAX2]; /* The multi-dimensional array */
    >
    >
    > So, mArray is an array of pointers to CELLs. And each CELL contains a
    > symbol and pointers to the neighbouring CELLs. I am representing a 4d
    > "grid" here, but you can think of it like a 2d one.
    >
    > Note the boundary CELLS should not point to anything, e.g. the first
    > piece in a row should have a prev_in_block value of NULL, meaning the
    > address of the CELL it points to is NULL, meaning there's no such CELL.
    >
    > Ok, my problem comes when trying to ACCESS symbols via the pointers,
    > e.g. printing out the symbol in a "square" in the grid and all of it's
    > surrounding symbols. Then I get an intermittent seg fault. This first
    > line is always ok:
    >
    > value = mArray[bb][cc][rr][vv]->symbol;
    >
    > But one or more of the following will cause a seg fault:
    >
    > pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    > nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    > pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    > nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    > pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    > nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;
    >
    >
    > I can't find a particular pattern with this, different "squares"
    > (changing bb,cc etc) crash it at different lines - it seems to be no
    > relation to which squares have a NULL pointer for example.
    >
    > But, some of the statements above work correctly some of the
    > time...leading me to believe I have the syntax correct. So what could be
    > the issue? If there's any other information needed happy to provide.
    >
    > cheers,
    >
    > Ben



    Correction, my late night testing was obviously a little flawed. The above lines do only crash when trying to access one of the
    "NULL pointers"...so I guess I can do something like this:

    pointer = mArray[bb][cc][rr][vv]->prev_in_block;
    if (pointer != NULL) pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    else pib = '_';

    But is there a better way? Too many ifs already in this program :)
     
    Ben, Jun 9, 2006
    #2
    1. Advertising

  3. Ben wrote:
    [...]
    > > But one or more of the following will cause a seg fault:
    > >
    > > pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    > > nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    > > pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    > > nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    > > pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    > > nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;

    [...]
    > Correction, my late night testing was obviously a little flawed. The
    > above lines do only crash when trying to access one of the
    > "NULL pointers"...so I guess I can do something like this:
    >
    > pointer = mArray[bb][cc][rr][vv]->prev_in_block;
    > if (pointer != NULL) pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    > else pib = '_';
    >
    > But is there a better way? Too many ifs already in this program :)


    Several things. First, don't recalculate "mArray[bb][cc][rr][vv]" for
    each line. Even if the compiler optimizes it to only once, it makes
    your source more cluttered.

    Second, you can use the "?:" operator. In your example using "pib"
    above, this can be written:

    pib = (mArray[bb][cc][rr][vv]->prev_in_block == NULL) ? '_'
    : mArray[bb][cc][rr][vv]->prev_in_block->symbol;

    Combining the two, and using a simple macro-wrapper, you have:

    ========== (Untested)

    pCELL *pcell;

    pcell = mArray[cc][cc][rr][vv];
    #define DOIT(dest,src) \
    dest = ( (pcell->what == NULL ) ? '_' : pcell->what->symbol )
    DOIT(pib,prev_in_block);
    DOIT(nib,next_in_block);
    DOIT(pic,prev_in_column);
    ...
    #undef DOIT

    ==========

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jun 9, 2006
    #3
  4. Ben

    Ben Guest

    Kenneth Brody wrote:
    > Ben wrote:
    > [...]
    >>> But one or more of the following will cause a seg fault:
    >>>
    >>> pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >>> nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    >>> pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    >>> nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    >>> pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    >>> nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;

    > [...]
    >> Correction, my late night testing was obviously a little flawed. The
    >> above lines do only crash when trying to access one of the
    >> "NULL pointers"...so I guess I can do something like this:
    >>
    >> pointer = mArray[bb][cc][rr][vv]->prev_in_block;
    >> if (pointer != NULL) pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >> else pib = '_';
    >>
    >> But is there a better way? Too many ifs already in this program :)

    >
    > Several things. First, don't recalculate "mArray[bb][cc][rr][vv]" for
    > each line. Even if the compiler optimizes it to only once, it makes
    > your source more cluttered.
    >
    > Second, you can use the "?:" operator. In your example using "pib"
    > above, this can be written:
    >
    > pib = (mArray[bb][cc][rr][vv]->prev_in_block == NULL) ? '_'
    > : mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >
    > Combining the two, and using a simple macro-wrapper, you have:
    >
    > ========== (Untested)
    >
    > pCELL *pcell;
    >
    > pcell = mArray[cc][cc][rr][vv];
    > #define DOIT(dest,src) \
    > dest = ( (pcell->what == NULL ) ? '_' : pcell->what->symbol )
    > DOIT(pib,prev_in_block);
    > DOIT(nib,next_in_block);
    > DOIT(pic,prev_in_column);
    > ...
    > #undef DOIT
    >
    > ==========
    >

    Thanks, I think I can cut my program by 400 lines with this
     
    Ben, Jun 10, 2006
    #4
  5. Ben

    Ben Guest

    Kenneth Brody wrote:
    > Ben wrote:
    > [...]
    >>> But one or more of the following will cause a seg fault:
    >>>
    >>> pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >>> nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    >>> pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    >>> nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    >>> pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    >>> nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;

    > [...]
    >> Correction, my late night testing was obviously a little flawed. The
    >> above lines do only crash when trying to access one of the
    >> "NULL pointers"...so I guess I can do something like this:
    >>
    >> pointer = mArray[bb][cc][rr][vv]->prev_in_block;
    >> if (pointer != NULL) pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >> else pib = '_';
    >>
    >> But is there a better way? Too many ifs already in this program :)

    >
    > Several things. First, don't recalculate "mArray[bb][cc][rr][vv]" for
    > each line. Even if the compiler optimizes it to only once, it makes
    > your source more cluttered.
    >
    > Second, you can use the "?:" operator. In your example using "pib"
    > above, this can be written:
    >
    > pib = (mArray[bb][cc][rr][vv]->prev_in_block == NULL) ? '_'
    > : mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >
    > Combining the two, and using a simple macro-wrapper, you have:
    >
    > ========== (Untested)
    >
    > pCELL *pcell;
    >
    > pcell = mArray[cc][cc][rr][vv];
    > #define DOIT(dest,src) \
    > dest = ( (pcell->what == NULL ) ? '_' : pcell->what->symbol )
    > DOIT(pib,prev_in_block);
    > DOIT(nib,next_in_block);
    > DOIT(pic,prev_in_column);
    > ...
    > #undef DOIT
    >
    > ==========
    >


    Having a go at this, I am getting "assignment makes pointer from integer without a cast" errors from the lines starting with DOIT.

    pCELL pointer,pib,nib,pic;
    pointer = mArray[0][0][0][0];

    #define DOIT(dest,src) \
    dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    DOIT(pib,prev_in_block);
    DOIT(nib,next_in_block);
    DOIT(pic,prev_in_column);
    #undef DOIT

    Note that type pCELL IS a pointer to CELL structures, so

    pCELL pointer,pib,nib,pic;

    should be correct.

    I would have thought that dest, should actually be *dest since we are assigning a value to a pointer, but am not familiar enough
    with macros (or C) to know if this should work. Can anyone else see the problem? Here's the full code I am using to test:

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

    #define MAX 8
    #define MAX2 64

    typedef char SYMBOL;
    typedef struct CELL *pCELL;
    struct CELL {
    SYMBOL symbol;
    int block,column,row;
    pCELL prev_in_block;
    pCELL prev_in_column;
    pCELL prev_in_row;
    pCELL next_in_block;
    pCELL next_in_column;
    pCELL next_in_row;
    pCELL next_in_vector;
    pCELL next_in_puzzle;
    };
    pCELL mArray[MAX2][MAX][MAX][MAX2];

    int main(void) {

    pCELL pointer,pib,nib,pic;
    pointer = mArray[0][0][0][0];

    #define DOIT(dest,src) \
    dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    DOIT(pib,prev_in_block);
    DOIT(nib,next_in_block);
    DOIT(pic,prev_in_column);
    #undef DOIT

    return 0;
    }
     
    Ben, Jun 11, 2006
    #5
  6. Ben wrote:
    [...]
    > Having a go at this, I am getting "assignment makes pointer from
    > integer without a cast" errors from the lines starting with DOIT.
    >
    > pCELL pointer,pib,nib,pic;
    > pointer = mArray[0][0][0][0];
    >
    > #define DOIT(dest,src) \
    > dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    > DOIT(pib,prev_in_block);
    > DOIT(nib,next_in_block);
    > DOIT(pic,prev_in_column);
    > #undef DOIT
    >
    > Note that type pCELL IS a pointer to CELL structures, so
    >
    > pCELL pointer,pib,nib,pic;
    >
    > should be correct.

    [...]
    > typedef char SYMBOL;

    [...]

    Well, since pib/nib/pic/etc are all type pCELL (ie: a pointer to CELL),
    and both '_' and "...->symbol" are of type SYMBOL (ie: char), what is it
    that you are trying to do with the assignment?

    Your original post didn't specify what SYMBOL is not what type pib is,
    so I had to assume that the assignment was okay. (You didn't say that
    you were getting any errors/warnings on the compile.)

    Taking a line from your original post:

    pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;

    The macro should be expanding to the same assignment, with the NULL
    check as you discovered you needed.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jun 12, 2006
    #6
  7. "Ben" <> wrote in message
    news:...
    > Hi,
    >
    > I am having trouble debugging a segmentation fault...here's my data
    > structure:
    >
    > typedef struct CELL *pCELL; /* Pointers to cells */
    > struct CELL {
    > SYMBOL symbol;
    > pCELL prev_in_block;
    > pCELL next_in_block;
    > pCELL prev_in_column;
    > pCELL next_in_column;
    > pCELL prev_in_row;
    > pCELL next_in_row;
    > };
    > pCELL mArray[MAX2][MAX][MAX][MAX2]; /* The multi-dimensional array */
    >
    >
    > So, mArray is an array of pointers to CELLs. And each CELL contains a
    > symbol and pointers to the neighbouring CELLs. I am representing a 4d
    > "grid" here, but you can think of it like a 2d one.
    >
    > Note the boundary CELLS should not point to anything, e.g. the first piece
    > in a row should have a prev_in_block value of NULL, meaning the address of
    > the CELL it points to is NULL, meaning there's no such CELL.
    >
    > Ok, my problem comes when trying to ACCESS symbols via the pointers, e.g.
    > printing out the symbol in a "square" in the grid and all of it's
    > surrounding symbols. Then I get an intermittent seg fault. This first line
    > is always ok:
    >
    > value = mArray[bb][cc][rr][vv]->symbol;
    >
    > But one or more of the following will cause a seg fault:
    >
    > pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    > nib = mArray[bb][cc][rr][vv]->next_in_block->symbol;
    > pic = mArray[bb][cc][rr][vv]->prev_in_column->symbol;
    > nic = mArray[bb][cc][rr][vv]->next_in_column->symbol;
    > pir = mArray[bb][cc][rr][vv]->prev_in_row->symbol;
    > nir = mArray[bb][cc][rr][vv]->next_in_row->symbol;
    >
    >
    > I can't find a particular pattern with this, different "squares" (changing
    > bb,cc etc) crash it at different lines - it seems to be no relation to
    > which squares have a NULL pointer for example.
    >
    > But, some of the statements above work correctly some of the
    > time...leading me to believe I have the syntax correct. So what could be
    > the issue? If there's any other information needed happy to provide.
    >
    > cheers,
    >
    > Ben


    You declared mArray as a 4D array of pointers. Yet you haven't pointed any
    of the members to anything. Thus mArray[bb][cc][rr][vv] is an uninitialized
    pointer, so dereferencing it with the
    -> operator leads to undefined behavior and usually crashes.


    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Technical Architect, Software Reuse Project
     
    Fred Kleinschmidt, Jun 12, 2006
    #7
  8. Ben

    Ben Guest

    Kenneth Brody wrote:
    > Ben wrote:
    > [...]
    >> Having a go at this, I am getting "assignment makes pointer from
    >> integer without a cast" errors from the lines starting with DOIT.
    >>
    >> pCELL pointer,pib,nib,pic;
    >> pointer = mArray[0][0][0][0];
    >>
    >> #define DOIT(dest,src) \
    >> dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    >> DOIT(pib,prev_in_block);
    >> DOIT(nib,next_in_block);
    >> DOIT(pic,prev_in_column);
    >> #undef DOIT
    >>
    >> Note that type pCELL IS a pointer to CELL structures, so
    >>
    >> pCELL pointer,pib,nib,pic;
    >>
    >> should be correct.

    > [...]
    >> typedef char SYMBOL;

    > [...]
    >
    > Well, since pib/nib/pic/etc are all type pCELL (ie: a pointer to CELL),
    > and both '_' and "...->symbol" are of type SYMBOL (ie: char), what is it
    > that you are trying to do with the assignment?
    >
    > Your original post didn't specify what SYMBOL is not what type pib is,
    > so I had to assume that the assignment was okay. (You didn't say that
    > you were getting any errors/warnings on the compile.)
    >
    > Taking a line from your original post:
    >
    > pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >
    > The macro should be expanding to the same assignment, with the NULL
    > check as you discovered you needed.
    >


    Yes, you're correct, pib etc should have been type SYMBOL, not pCELL...here's some (complete) working code for example:

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

    #define MAX 8 /* Maximum value of n */
    #define MAX2 64 /* Maximum value of n2 */

    typedef char SYMBOL;
    typedef struct CELL *pCELL;
    struct CELL {
    SYMBOL symbol;
    int block,column,row;
    pCELL prev_in_block;
    pCELL next_in_block;
    pCELL prev_in_column;
    };
    pCELL mArray[MAX2][MAX][MAX][MAX2];

    int main(void) {

    pCELL pointer;
    SYMBOL pib,nib,pic;

    pointer = mArray[0][0][0][0];

    #define DOIT(dest,src) \
    dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    DOIT(pib,prev_in_block);
    DOIT(nib,next_in_block);
    DOIT(pic,prev_in_column);
    #undef DOIT

    return 0;
    }
     
    Ben, Jun 13, 2006
    #8
  9. Ben

    Ben Guest

    Kenneth Brody wrote:
    > Ben wrote:
    > [...]
    >> Having a go at this, I am getting "assignment makes pointer from
    >> integer without a cast" errors from the lines starting with DOIT.
    >>
    >> pCELL pointer,pib,nib,pic;
    >> pointer = mArray[0][0][0][0];
    >>
    >> #define DOIT(dest,src) \
    >> dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    >> DOIT(pib,prev_in_block);
    >> DOIT(nib,next_in_block);
    >> DOIT(pic,prev_in_column);
    >> #undef DOIT
    >>
    >> Note that type pCELL IS a pointer to CELL structures, so
    >>
    >> pCELL pointer,pib,nib,pic;
    >>
    >> should be correct.

    > [...]
    >> typedef char SYMBOL;

    > [...]
    >
    > Well, since pib/nib/pic/etc are all type pCELL (ie: a pointer to CELL),
    > and both '_' and "...->symbol" are of type SYMBOL (ie: char), what is it
    > that you are trying to do with the assignment?
    >
    > Your original post didn't specify what SYMBOL is not what type pib is,
    > so I had to assume that the assignment was okay. (You didn't say that
    > you were getting any errors/warnings on the compile.)
    >
    > Taking a line from your original post:
    >
    > pib = mArray[bb][cc][rr][vv]->prev_in_block->symbol;
    >
    > The macro should be expanding to the same assignment, with the NULL
    > check as you discovered you needed.
    >


    Yes, you're correct, pib etc should have been type SYMBOL, not pCELL...here's some (complete) working code for example:

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

    #define MAX 8 /* Maximum value of n */
    #define MAX2 64 /* Maximum value of n2 */

    typedef char SYMBOL;
    typedef struct CELL *pCELL;
    struct CELL {
    SYMBOL symbol;
    int block,column,row;
    pCELL prev_in_block;
    pCELL next_in_block;
    pCELL prev_in_column;
    };
    pCELL mArray[MAX2][MAX][MAX][MAX2];

    int main(void) {

    pCELL pointer;
    SYMBOL pib,nib,pic;

    pointer = mArray[0][0][0][0];

    #define DOIT(dest,src) \
    dest = ( (pointer->src==NULL) ? '_' : pointer->src->symbol )
    DOIT(pib,prev_in_block);
    DOIT(nib,next_in_block);
    DOIT(pic,prev_in_column);
    #undef DOIT

    return 0;
    }
     
    Ben, Jun 13, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Goh, Yong Kwang
    Replies:
    3
    Views:
    11,876
    Barry Schwarz
    Apr 3, 2004
  2. Chris Van Extergem

    Function pointer results in segmentation fault.

    Chris Van Extergem, May 1, 2006, in forum: C Programming
    Replies:
    5
    Views:
    886
    Chris Van Extergem
    May 2, 2006
  3. esanchezfo

    Segmentation fault char array pointer

    esanchezfo, Jun 1, 2006, in forum: C Programming
    Replies:
    1
    Views:
    457
    Fred Kleinschmidt
    Jun 1, 2006
  4. Replies:
    1
    Views:
    434
  5. H.S.
    Replies:
    9
    Views:
    772
    Richard Herring
    Aug 13, 2008
Loading...

Share This Page