Pthreads update on global 2D array segfaults on execution - c

Hi all and thanks for your time.
I am trying to parallelise a program which executes some commands and I thought pthreads would be a good option.
But I am running into some issues.
This is where I start the threads:
void timetravel(command_stream_t s)
{
int *retvals[MAXTHREADS];
if (s == NULL)
return;
if (s->num_commands == 0)
return;
int err;
global_table = create_dependency_table(s);
//global_command = &s;
global_command = s;
int fill = 0;
for (fill = 0; fill < s->num_commands; fill++)
{
global_table.status_table[fill] = 1; //Set all commands to waiting
// printf("global_table.status_table[i] : %d \n", global_table.status_table[fill]);
}
int finished = 0;
while (finished == 0)
{
finished++;
int threadindex = 0;
for (threadindex = 0; threadindex < MAXTHREADS; threadindex++)
{
err = pthread_create(&(tid[threadindex]), NULL, &parallelexecute, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
}
for (threadindex = 0; threadindex < MAXTHREADS; threadindex++)
{
pthread_join(tid[threadindex], NULL);
}
if (completecheck(global_table) == 0)
{
finished = 1;
}
}
// print_dependency_table(global_table);
//print_command(global_command->command_array[1]);
}
The dependency table is stored as such
*** DEPENDENCY TABLE ***
~x~ ~meh~ ~hello~ ~goodbye~ ~phi~ ~a~ ~gamma~ ~delta~ ~b~ ~c~ ~d~ ~e~ ~f~ ~g~
1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1
for the commands
cat x meh
echo hello
echo -s hello goodbye > phi
touch a < gamma > delta
touch -rx b c d e f g
As "hello" is used in command 2 and 3, 3 is dependent on 2 and so we have
~x~ ~meh~ ~hello~ ~goodbye~ ~phi~ ~a~ ~gamma~ ~delta~ ~b~ ~c~ ~d~ ~e~ ~f~ ~g~
0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0 0 0 0 0
So we will not run 3 before 2
After 2 is run, we set its row to 0, so 3 is no longer dependent on it
I have not implemented blocking of any kind because there are no Write/Write conflicts.
We might have a race condition where there is a read before a write, but that is fine - as it only delays thread execution which is ok.
This is the pthreads program:
void* parallelexecute(void *arg)
{
//printf("gets to parallel execute stage\n");
int i;
//printf("global_table.num_cmds_rows : %d \n",global_table.num_cmds_rows);
for (i = 0; i < global_table.num_cmds_rows; i++)
{
// status 1 = runnable, status 2 = running
//status 0 = completed successfully, status -1 = unsuccessful
//printf("global_table.status_table[i] : %d \n",global_table.status_table[i]);
if (global_table.status_table[i] == 1
&& (check_nth_command(&global_table, i)) == 0)
{
global_table.status_table[i] = 2;
execute_command(global_command->command_array[i], 0);
printf("execution triggered");
completed_nth_command(&global_table, i, 0);
break;
}
}
return NULL;
}
These are my global variables
#define MAXTHREADS 2
pthread_t tid[MAXTHREADS];
//global variable for dependency pool
parallel_data global_table;
//global variable for commands
command_stream_t global_command;
But I notice when I try to access global_table from parallelexecute I get all sorts of odd values and I am not sure why.
'global table' is a struct thus:
struct parallel_data
{
int** dependency_table; // the main dependency table
char** file_reference_key; // find index by name (use strcmp in a loop)
int* status_table; // you know you are done when all the statuses are 0 (none should ever be -1)
int num_files_cols; // number of columns/files
int num_cmds_rows; // number of rows/commands
};
And each thread WRITES only on its row in dependency table, and its row in status_table
I am not quite sure how to proceed.
I am also reasonably certain of the supporting functions correctness.
Any help would be appreciated.

I haven't read your code yet, but I saw "I have not implemented blocking of any kind because there are no Write/Write conflicts", That's a MAJOR red flag to me. If you have Read/Write conflicts, then... well... you have conflicts. That's probably related to the bug. The only time it's valid is if you have std::atomic variables or volatile variables, and a quick CTRL+F says you have neither. Your code is probably not synchronizing at all, and thus threads are never seeing the values that the other threads are writing.

I figured out that my style of passing arguments to the pthreads thread function was incorrect - I shall post the edits I made to the code shortly.
Thank you #mooing-duck , #wilx

Related

I cannot understand core dump cause of fgetc, how can I fix it?

I allocated matrix like this :
prevMatrix = (int**)malloc(sizeof(int) * arraySize[0]);
for (int i = 0; i < arraySize[0]; i++) {
prevMatrix[i] = (int*)malloc(sizeof(int) * arraySize[1]);
}
I checked arraySize[] has normal value. arraySize[0] means row, and arraySize[1] means column.
and I handed over the matrix like this :
void getInputMatrix(FILE* input, int column, int** matrix)
getInputMatrix(input, arraySize[1], prevMatrix);
and then function's body is this :
void getInputMatrix(FILE* input, int column, int** matrix) {
int i = 0, j = 0, c = 0;
while (!feof(input)) {
if (j == column) {
j = 0;
i++;
}
c = fgetc(input);
if (c != EOF && c != 32 && c != 10 && c != 13) {
matrix[i][j] = c - 48;
j++;
}
}
}
this is the example of matrix file:
1 0 0 0 0 0 0
0 1 0 1 0 0 0
0 1 0 0 1 1 0
0 1 1 1 0 0 0
0 0 0 0 1 0 0
0 1 0 0 0 1 0
1 0 1 1 0 0 0
0 1 0 0 0 0 1
It works very well in VS 2019, but it cause segmentation fault in Linux system(Ubuntu).
This program works well in Linux till the column is 6 or 7, but it occurs corrupted size vs. prev_size error or segmentation faultwhen the column overs that number.
Is it a problem of allocation? or fgetc()?
How can I fix it?
For starters, your first level allocation should be using the size of an int pointer rather than an int:
int **prevMatrix = malloc(sizeof(int*) * arraySize[0]);
If those types are different sizes, your original code could have a problem.
And, just as an aside, you should not cast the malloc return value in C, it can cause subtle problems.

Adjacency matrix of graph in c ( getting error )

#include <stdio.h>
struct graph{
int v,e,**adj;
};
struct graph* graph_A(){
int u,V,i;
struct graph *g = (struct graph*)malloc(sizeof(struct graph));
if(!g){
printf("error ! ");
exit(1);
}
printf("Enter no of nodes and edges ? ");
scanf("%d, %d",&g->v,&g->e);
g->adj = (int**)malloc(sizeof(int) * sizeof(g->v * g->v ));
for(u = 0 ; u <= g->v ; u++)
for(V = 0 ; V <= g->v ; V++ )
g->adj[u][V] = 0;
printf("Enter connections ? ");
for(i = 0 ; i <= g->e ; i++){
scanf("%d, %d",&u,&V);
g->adj[u][V] = 1;
g->adj[V][u] = 1;
}
return (g);
}
int main(){
graph_A();
}
I am trying to figure out whats the problem but unable to resolve by myself . please help !
i've researched for about 2 hours over this topic unfortunately did't found any
proper help desk.
i am learning data structure and implementing in c and c++ language.
if you could able to advice me
that'd be earnestly kind of you .
thanks !
Slightly fixed your code using vectors. Not the cleaniest way due to non-use of auto loops, bad choices of variables, no boundary check on user input, but at least it works
I have removed the allocations fully, replaced by vectors, much simpler, and the fact is that the code did not change that much.
Note that you don't need a graph class. Everything could have been done in the main itself. If you want to create a class, then provide parameters in the constructor instead of interactive input (do that in the main so others can reuse your class for other purposes), and provide methods to compute, get access to data, size, etc... That will come afterwards.
Which were the main concerns:
malloc of the instance within the constructor itself. Using new would have created an infinite recursion. My advice: read some C++ books
all loops include upper boundary
the pointer of pointer row was allocated but not the rows themselves.
When I rewrote the code, I had 2 compilation errors, one SEGV because of the last upper bound boundary error on the display part, after that it worked right away. C++ rules (when you know your way around)
code:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
class graph{
int v,e;
vector<vector<int> > adj;
public:
graph();
};
graph::graph()
{
int u,V,i;
cout << "Enter no of nodes and edges ? ";
cin >> v ;
cin >> e ;
adj.resize(v);
for(u = 0 ; u < v ; u++)
{
adj[u].resize(v);
}
for(u = 0 ; u < v ; u++)
for(V = 0 ; V < v ; V++ )
adj[u][V] = 0;
cout << " Enter connections ? ";
for(i = 0 ; i < e ; i++){
cin >> u ;
cin >> V ;
adj[u][V] = 1;
adj[V][u] = 1;
}
for(u = 0 ; u < v ; u++)
{
for(V = 0 ; V < v ; V++ )
{
cout << adj[u][V] << " ";
}
cout << endl;
}
}
int main(){
graph a;
return 0;
}
test:
Enter no of nodes and edges ? 10 3
Enter connections ? 3 4
2 3
4 5
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 1 0 0 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Dynamic 2D array elements are not accessible several for loop

I've studied data structure and algorithm, and I got a problem with dynamic 2d array. Here is part of my code. The coding problem is the Knight's tour.
int iMove[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int jMove[8] = { 1, 2, 2, 1,-1, -2, -2, -1};
cell* cellList(int* i, int* j, int** board){
int k;
cell* temp;
int iTempNext; int jTempNext;
int maxSampleNum = 8;
int cnt = 0;
int val;
for(k = 0; k < maxSampleNum; k++){
iTempNext = (*i) + iMove[k];
jTempNext = (*j) + jMove[k];
//1. get list 0<=i<=7 && 0<=j<=7
if( (0 <= iTempNext && iTempNext <= 7) && (0 <= jTempNext && jTempNext <= 7)){
//2. get the 0 value cells
//val = canMove(iTempNext, jTempNext, board);
printf("%d %d\n", iTempNext, jTempNext);
if(board[iTempNext][jTempNext] == 0){
cell tempCell;
tempCell.row = iTempNext;
tempCell.col = jTempNext;
temp = (cell*)realloc(temp, sizeof(cell));
*(temp+cnt) = tempCell;
cnt++;
}
}
}
return temp;
}
int** board : 2d array and I allocated it dynamically and initialized all elements of this array to 0. I printed 2d array after initializing.
The problem is that after 2nd for loop, this program got segmentation fault on accessing 2d array. I cannot access 2d array elements during 3rd for loop.
Initializing Complete...
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Enter the start position (i, j): 3 3
iTempNext jTempNext
1 4
2 5
4 5
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400b1c in cellList (i=0x7fffffffe5bc, j=0x7fffffffe5c0, board=0x603010) at main.c:144
144 if(board[iTempNext][jTempNext] == 0){
this is the result after using gdb. How can I solve this problem
This line:
temp = (cell*)realloc(temp, sizeof(cell));
invokes undefined behaviour since temp is not initialized. You should initialize it with, e.g., cell *temp = NULL; (understand that realloc can either take a NULL pointer in which case it is equivalent to malloc, or a previously malloced/calloced/realloced pointer).
And don't cast the return from malloc. This is C, not C++. Search this site for why casting the malloc return value is frowned upon in C.

Segfault while allotting 2D array using double dimensional pointer

I'm currently working on a codechef practice problem http://www.codechef.com/problems/STEPUP#
I'm trying to set up a 2D array using pointers to accept the data and enter in into the 2D array as i receive it using scanf.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
int m,n,i,k,j;
int ex;
scanf("%d",&ex);
for(i=0;i<ex;i++)
{
int **edgegraph=NULL,temp1,temp2;
scanf("%d %d",&n,&m);
edgegraph=malloc(m*sizeof(int));
for(k=0;k<m;k++)
{
*(edgegraph+k)=malloc(m*sizeof(int));
if(!*(edgegraph+k))
exit(0);
}
for(k=0;k<m;k++)
{
scanf("%d %d",&temp1,&temp2);
*(*(edgegraph+m*temp1)+temp2)=1;
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
printf("%d ",*(*(edgegraph+m*i)+j));
printf("\n");
}
}
}
The error i get is
(gdb) run
Starting program: /home/vishwa/codechef/valid
2
2 2
1 2
Program received signal SIGSEGV, Segmentation fault.
0x000000000040079d in main (argc=1, argv=0x7fffffffded8) at validedge.c:24
24 *(*(edgegraph+m*temp1)+temp2)=1;
(gdb) quit
What I intend to do is create an m*m matrix, set all valid edges to 1 and then sort in ascending order of number of edges. I'm unsure if this will solve the problem, but would like to know where I'm messing up.
You malloc the wrong number of bytes: edgegraph=malloc(m*sizeof(int)); should have malloc(m * sizeof(int *)); . To avoid this sort of error you can use the following pattern:
ptr = malloc( N * sizeof *ptr );
which always allocates N of whatever ptr is a pointer to.
Next, the syntax x[y] is much simpler to read than *(x+y) especially when the expressions get complicated. Using that syntax would have avoided the mistake dconman points outs. You seem to have put an extra m * into your calculation where it is not required.
Also you mix up m and n later in your code. To avoid this sort of error, use more descriptive variable names.
So a fixed version of your allocation code could look like:
if ( 2 != scanf("%d %d",&num_edges, &num_vertices) )
exit(EXIT_FAILURE);
edgegraph = malloc( num_vertices * sizeof *edgegraph );
for (int vertex = 0; vertex < num_vertices; ++vertex)
{
edgegraph[vertex] = malloc( num_vertices * sizeof **edgegraph );
if ( edgegraph[vertex] == NULL )
exit(EXIT_FAILURE);
}
Note that it is possible to replace that malloc series with a single allocation:
int (*edgegraph)[num_vertices] = malloc( num_vertices * sizeof *edgegraph );
Moving onto your code to read edges. You wrote for(k=0;k<m;k++) however I think you meant n there. Using more descriptive variable names and the x[y] syntax:
for(int edge = 0; edge < num_edges; ++edge)
{
if ( 2 != scanf("%d %d",&temp1,&temp2) )
exit(EXIT_FAILURE);
if ( temp1 < 0 || temp1 >= num_vertices || temp2 < 0 || temp2 >= num_vertices )
exit(EXIT_FAILURE); // maybe display an error message
edgegraph[temp1][temp2] = 1;
edgegraph[temp2][temp1] = 1; // add this if undirected graph!
}
Now the final loop, for(i=0;i<m;i++). You have used the same variable i as control variable for this loop and for your outer loop. To avoid this sort of error, use scoped control variables:
for (int i = 0; i < num_edges; ++i)
Finally you will need to free the memory you malloc'd at the end of each time around the outer loop.
You are so close: lose the m* in your expressions to access an array element. Remember, you set up your 2d array as an array of rows, each with its own pointer (you allocated each independently).
*(*(edgegraph+m*temp1)+temp2)=1;
should be
*(*(edgegraph+temp1)+temp2)=1;
And the same change where you do that later in your code.
Is there a reason you are not using array indices?
EDIT
here is my input
2
10
10
4 3
4 9
7 3
3 7
4 3
4 5
7 4
3 5
9 0
5 2
And I got this output
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0 1
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0

Having problems with a cellular automation in C

Now having corrected all of the errors thrown up by GCC, the output is different than before, but still only changes once.
OUTPUT:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1
It stays like this for 40 passes, which it shouldn't
THE NEW (WARNING FREE) CODE:
signed char board [10][10]; //the board
int evaluate_cell (int i, int a);
int evaltheboard(void){
//loops through the array, and stops to check if there is a living cell. leiving cells are represented by a 1.
int i,a;
signed char cell_to_check [1][1];
for (a=0;a<=9;a++){
for (i=0;i<=9;i++){
cell_to_check[0][0] = board[i][a];
if (cell_to_check[0][0] != 0){
evaluate_cell(i,a);
}
}
}
return 0;
}
int evaluate_cell(int i,int a){
// checks near by cells to see if there are any living and chooses whether the cell should live based off of it's living neighbors.
signed char live_n_cells = 0, empty_x_mod, empty_y_mod;
signed char x_inc [8] = {0,1,1,1,0,-1,-1,-1}, y_inc [8]={-1,-1,0,1,1,1,0,-1};
int z, x, y;
x=y=0;
//printf("evaling cell\n");
//printf ("co-ords being checked [%d][%d]", i,a);
for (z=0;z<=7;z++){
if (board[(i+(x_inc[x]))][(a+(y_inc[y]))] != 0){
++live_n_cells;
}
else if(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0){
empty_x_mod = i-(x_inc[x]) ;
empty_y_mod = a-(y_inc[y]);
}
y++;
x++;
}
//printf("%d = z, %d = y, %d = x\n", z, y, x);//debug
//printf("|close living cells = %d\n", live_n_cells); // debug
//printf("|empty mods are %d %d\n", empty_x_mod, empty_y_mod); //debug
if (live_n_cells >= 3){
board[i][a] = 0;
}
else if (live_n_cells == 0){
board[i][a] = 0;
}
else if (live_n_cells == 1 || 2){
board[empty_x_mod][empty_y_mod] = 1;
}
return 0;
}
int print_array(void){
//prints array
int i,a;
for (a=0;a<=9;a++){
for (i=0;i<=9;i++){
printf(" %d", board[i][a]);
//printf("%d", i);
}
printf("\n");
}
printf("----------\n");
return 0;
}
int main(void){
int x;
//runs the damned thing
board[5][5] = 1; //DEBUG
board[5][6] = 1; //DEBUG
board[6][5] = 1; //DEBUG
for (x=0;x<40;x++){
evaltheboard();
print_array();
}
return 0;
}
OLD QUESTION:
Like the title says, i am having some unexpectedly stagnant output. The program should function like Conway's Game of Life. When i run this version, it changes the 'board' array once and doesn't seem to do it again. the out put ends up looking like this (0 = empty cell, 1 = living cell):
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0
So in theory, the two adjacent ones should have re-populated and the isolated ones should have died off, but they didn't. Any help into why this would be would be met with thanks.
Please don't be too harsh, this is my first actually project in c that I have written from the ground up. Any feed back on my general form of code would be appericieated
THE CODE:
signed char board [10][10]; //the board
int evaltheboard(void){
//loops through the array, and stops to check if there is a living cell. living cells are represented by a 1.
int i,a;
signed char cell_to_check [1][1] = {0};
for (a=0;a<=9;a++){
for (i=0;i<=9;i++){
cell_to_check[0][0] = board[i][a];
if (cell_to_check[0][0] != 0){
evaluate_cell(i,a);
}
}
}
return 0;
}
int evaluate_cell(int i,int a){
// checks near by cells to see if there are any living and chooses whether the cell should live based off of it's living neighbors.
signed char live_n_cells = 0, empty_x_mod, empty_y_mod;
signed char x_inc [8] = {0,1,1,1,0,-1,-1,-1}, y_inc [8]={-1,-1,0,1,1,1,0,-1};
int z, x, y;
x=y=0;
//printf("evaling cell\n");
//printf ("co-ords being checked [%d][%d]", i,a);
for (z=0;z<=7;z++){
if (board[(i+(x_inc[x]))][(a+(y_inc[y]))] != 0){
++live_n_cells;
}
else(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0);{
empty_x_mod = i-(x_inc[x]) ;
empty_y_mod = a-(y_inc[y]);
y++;
x++;
}
}
//printf("%d = z, %d = y, %d = x\n", z, y, x);//debug
//printf("|close living cells = %d\n", live_n_cells); // debug
//printf("|empty mods are %d %d\n", empty_x_mod, empty_y_mod); //debug
if (live_n_cells >= 3){
board[i][a] = 0;
}
else if (live_n_cells = 0){
board[i][a] = 0;
}
else(live_n_cells = 1 || 2);{
board[empty_x_mod][empty_y_mod] = 1;
}
return 0;
}
int print_array(void){
//prints array
int i,a;
for (a=0;a<=9;a++){
for (i=0;i<=9;i++){
printf(" %d", board[i][a]);
//printf("%d", i);
}
printf("\n");
}
printf("----------\n");
return 0;
}
int main(void){
int x;
//runs the damned thing
board[5][5] = 1; //DEBUG
board[5][6] = 1; //DEBUG
board[6][5] = 1; //DEBUG
for (x=0;x<40;x++){
evaltheboard();
print_array();
}
return 0;
}
note: the printf's with //'s in front of them are for debugging only, and the forloop in main is only temporary. i plan to do a while that checks if any thing is still alive later. if it says //DEBUG afterwards, it is also temporary.
anyway, Thanks!
There are a few things you need to look at in your code. The best thing you could do is enable compiler warnings, if you are using gcc add the -Wall (warn all) flag to the compile line, so to compile use:
gcc -Wall source.c -o Program
Most compilers support some sort of warning flag/option. When I compiled your code with this flag I got the following output (trimmed a bit):
7:5: warning: missing braces around initializer [-Wmissing-braces]
signed char cell_to_check [1][1] = {0};
31:13: warning: statement with no effect [-Wunused-value]
else(board[(i+(x_inc[x]))][(a+(y_inc[y]))] == 0);{
44:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
else if (live_n_cells = 0){
12:17: warning: implicit declaration of function ‘evaluate_cell’ [-Wimplicit-function-declaration]
evaluate_cell(i,a);
When I went through and fixed these issues, the compiler provided more issues, but eventually you should have a nice warning free program (suggesting that your code might be correct).
The first warning above is because you are trying to assign an array with one element to a variable which expects an array of and array with one element.
The second warning above is because you are missing an if after your else, so this should be else if (...), however something else you should note is that you have a ; before the curly brackets, this probably shouldn't be there at all, you should go through your code an make sure you don't have extra ;s before curlly brackets.
The third warning is probably because you are making an assignment live_n_cells = 0 instead of checking live_n_cells == 0. If you actually meant to make the assignment, then write (live_n_cells = 0). A good way to avoid every accidently making assignments is to use 0 == live_n_cells, this way if you forget the second equals sign you never make an assignment.
The fourth warning is about a missing declaration of your function. to resolve this, you can add something like int evaluate_cell(int i,int a); to the top of your source file.
Try these things and then post an update to your question (these tips may even help to solve your problem).
EDIT:
A few more tips:
Functions can be declared as void, which means that they don't return a value. This could be useful in your program since evaluate_cell currently returns 0, which you simply ignore. You could instead write void evaluate_cell(int i, int j), but remember to change the declaration at the top of your source file too.
I went over your reproduction code, it doesn't seem to contain all the Game of Life operations (at least according to the Wikipedia page http://en.wikipedia.org/wiki/Conway's_Game_of_Life), try the following:
if (live_n_cells == 3 && board[i][a] == 0) { // production
temp_board[i][a] = 1;
} else if (live_n_cells > 3) { // over population
temp_board[i][a] = 0;
} else if (live_n_cells < 2) { // under population
temp_board[i][a] = 0;
} else { // reproduction
temp_board[i][a] = board[i][a];
}
And also call your evaluate cell routine for all cells, not just the currently alive cells. You also probably notice the use of the variable temp_board in the above code. This is related to the comment posted by aschepler on your question. I also changed the definition of the board to the following, the +2 is padding to make sure you never try to access elements outside the array.
#define WIDTH 10
#define HEIGHT 10
signed char board [HEIGHT+2][WIDTH+2]; ///< the board
signed char temp_board [HEIGHT+2][WIDTH+2]; ///< temporary board
Finally, I changed the code in evaluateboard to:
int i, j; ///< loop counters
// Evaluate each cell in array
for (j=1; j<=HEIGHT; j++) {
for (i=1; i<=WIDTH; i++) {
evaluate_cell(j,i);
}
}
// copy temp_board into board
for (j=1; j<=HEIGHT; ++j) {
for (i=1; i<=WIDTH; ++i) {
board[j][i] = temp_board[j][i];
}
}
Using most of your code, with the above few tweaks, I managed to get Conway's Game of Life running with the expected results.
One final tip, it is usually the convention in C/C++ to use i, j, k, l, m, n (often in that order) as your loop counting variables.
Good luck. :)
There are some bugs in evaluate_cell.
First, when you check around a cell on the border, you access areas outside the board. You need to check if a surrounding cell is outside the board!
Second, you use assignment instead of comparison in your if statements.
You probably mean:
else if (live_n_cells == 0){ // = is assignment, == is equality
The else should probably be:
else { // Only way to get here is if live_n_cells is 1 or 2, so no need for a condition.

Resources