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