I'm writing an ncurses Scrabble clone in C.
I've written some code to represent a bag, which is a source of shuffled characters that you can pull characters out of, much like pulling random tiles out of a bag in real life.
My code works on OS X - but when I try to compile on a Debian machine, it gives me this blunt message:
~/nscrabble $ ./scrabble
Segmentation fault
I've used gdb to try to diagnose the problem. It appears that the segfault was caused on the return statement:
(gdb) run
Starting program: /home/jay/nscrabble/scrabble
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ca8 in bag () at bag.c:53
53 return b;
(gdb)
There you go. Here's the code (both bag.c and bag.h)
Here's bag.h --
#ifndef BAG_H_INCLUDED
#define BAG_H_INCLUDED
/*
* This array states how many times each
* letter should show up in the bag.
*
* distributions[0] Number of As
* distributions[1] Number of Bs
* ...
* distributions[25] Number of Zs
* distributions[26] Number of blank tiles
*/
const short distributions[27];
/*
* The bag is the repository of tiles in Scrabble.
* I didn't want to deal with storing pointers
* and freeing them constantly, so I decided to
* store chars.
*/
typedef struct bag {
char tiles[100];
size_t top;
/*
* Get a tile letter out of the bag.
* It removes the letter from the bag.
*/
char (*pop)( struct bag* );
} bag_t;
/*
* The constructor.
* Get a new bag using this.
*/
struct bag bag();
char bg_pop( struct bag* );
#endif
And here's bag.c --
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "bag.h"
const short distributions[27] = {
9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1,
6, 4, 6, 4, 2, 2, 1, 2, 1, 2
};
char bg_pop( struct bag* b )
{
return b->tiles[b->top--];
}
struct bag bag()
{
struct bag b;
for( char letter = 'A', count = 0; letter <= ']'; letter++ ) {
for(int i = 0; i < distributions[letter - 65]; i++, count++)
b.tiles[count] = letter;
}
srand( time(NULL) );
for( int i = 0; i < 3; i++, rand() )
;
for( int i = 0; i < 98; i++ ) {
int n = (rand() % (100 - i)) + i;
char temp = b.tiles[i];
b.tiles[i] = b.tiles[n];
b.tiles[n] = temp;
}
b.top = 100;
b.pop = bg_pop;
return b;
}
scrabble.c:
#include <stdio.h>
#include "bag.h"
int main( int argc, const char** argv )
{
struct bag b = bag();
for( int i = 0; i < 100; i++ )
printf("%3c", b.tiles[i]);
}
I know that the shuffling is being done correctly (at least on OS X).
Could someone please help shed some light as to what is happening here?
scrabble.cfile, though, that contains the main function. 1 sec.bag.c, but thebag.cyou posted doesn't contain that many lines.return b->tiles[b->top--];. Sinceb->topis initialised to100and thetilesarray is sized at100it appears that would cause an overflow. Also, it's unlikely that thereturnis causing the seg fault. Perhaps you have a code mismatch or some other gdb quirk in play.return bin the bag() method