Creating a matrix in C - c

I´m trying to create a dynamic matrix with an user introduzed number of lines and 6 columns.
I only want to create the matrix so I can get its values when I want to.
I have tried this but the program crashes when it gets here.
matriz = (int **)malloc(n_lines * 6 * sizeof(int *));
for (i = 0; i < n_lines; ++i)
{
for (j = 0; j < 6; ++j)
{
current_year = starting_year + i;
if (current_year % 400 == 0)
{
february = 29;
days = 366;
hours = 8784;
minutes = 527040;
seconds = 31622400;
}
else
{
february = 28;
days = 365;
hours = 8760;
minutes = 525600;
seconds = 31536000;
}
matriz[i][0] = { current_year };
matriz[i][1] = { february };
matriz[i][2] = { days };
matriz[i][3] = { hours };
matriz[i][4] = { minutes };
matriz[i][5] = { seconds };
}
}

Program crashed because you were accessing chunk of memory as if you have jagged allocated array which is not, resulting in invalid memory access in turn making your program crash.
Well from what I see - you messed up type. Two ways to go about this.
int **matriz;
matriz = malloc(sizeof *matriz*nlines);
// error check
for(size_t i=0; i<nlines; i++){
matriz[i]= malloc(sizeof *matriz[i] * 6);
// error check
}
int *matriz = malloc(6*nlines*sizeof *matriz);
// error check
matriz[r*6+c] = ... // accessing r-th row c-th column.
And based on case-1 it will be
matriz[i][j] = current_year ;
And in case-2 similarly
matriz[i*6+j] = current_year;
General code structure would be
if (current_year % 400 == 0)
{
...
seconds = 31622400;
}
else
{
...
seconds = 31536000;
}
for (j = 0; j < 6; ++j)
{
matriz[i][j] = current_year ;
...
}
To explain a bit - the first case is allocating a jagged array. First an array of pointers and then each of them are pointing to an array of 6 elements.
Second case is basically allocating a chunk of memory which has 6*nlines int and matriz is pointing to beginning of it. Now that's why you will have to access the elements first calculating the right index for it.

Related

C code bubble sorting sometimes does not give correct output

I am trying to sort numbers using the bubble sorting method. However, sometimes the output returns some incorrect answers.
Appreciate someone can help how to fix this issue. the C code and incorrect output as below
typedef struct
{
char pname[2];
int ptotime;
} data;
int main()
{
int totalwait = 0;
data name[] = {{'A', .ptotime = 4},
{'B', .ptotime = 6},
{'C', .ptotime = 3},
{'D', .ptotime = 7},
{'E', .ptotime = 2}};
printf("Process Name\t Process Time \n");
for (int j = 0; j < 5; j++)
{
printf("\t%s\t\t\t\t%d\n", name[j].pname, name[j].ptotime);
}
//Shortest job first (SJF) scheduling
printf("\nShortest job first (SJF) scheduling \n");
int swapped, temp;
while (1)
{
swapped = 0;
for (int x = 0; x < 5; x++)
{
if (name[x].ptotime >= name[x + 1].ptotime)
{
temp = name[x].ptotime;
name[x].ptotime = name[x + 1].ptotime;
name[x + 1].ptotime = temp;
swapped = 1;
char temp2[2];
strcpy(temp2, name[x].pname);
strcpy(name[x].pname, name[x + 1].pname);
stpcpy(name[x + 1].pname, temp2);
}
}
if (swapped == 0)
{
break;
}
}
printf("Process Name\t Process Time \n");
for (int j = 0; j < 5; j++)
{
printf("\t%s\t\t\t\t%d\n", name[j].pname, name[j].ptotime);
}
return 0;
}
Output
Process Name Process Time
A 4
B 6
C 3
D 7
E 2
Shortest job first (SJF) scheduling
Process Name Process Time
0
E 2
C 3
A 4
B 6
Expected output
Process Name Process Time
A 4
B 6
C 3
D 7
E 2
Shortest job first (SJF) scheduling
Process Name Process Time
E 2
C 3
A 4
B 6
D 7
For starters do not use magic numbers as 5. Use named constants.
The array name is initialized incorrectly. You are using character literals to initialize the data member pname of a character array type without enclosing character literals in braces.
data name[] = {{'A', .ptotime = 4},
^^^
//...
in this loop
for (int x = 0; x < 5; x++)
{
if (name[x].ptotime >= name[x + 1].ptotime)
^^^^^
//...
there is an access beyond the array. So the program has undefined behavior.
Use local variables as for example the variable swap in the shortest scope where they are used.
To swap elements of the array name there is no need to swap each data member of each element of the array. You can swap whole objects.
Here is a demonstrative program.
#include <stdio.h>
typedef struct
{
char pname[2];
int ptotime;
} data;
int main( void )
{
data name[] =
{
{ "A", .ptotime = 4 },
{ "B", .ptotime = 6 },
{ "C", .ptotime = 3 },
{ "D", .ptotime = 7 },
{ "E", .ptotime = 2 }
};
const size_t N = sizeof( name ) / sizeof( *name );
printf("Process Name\t Process Time \n");
for ( size_t i = 0; i < N; i++ )
{
printf( "\t%s\t\t\t\t%d\n", name[i].pname, name[i].ptotime );
}
putchar( '\n' );
//Shortest job first (SJF) scheduling
printf("\nShortest job first (SJF) scheduling \n");
for ( int swapped = 1; swapped; )
{
swapped = 0;
for ( int i = 1; i < N; i++ )
{
if ( name[i].ptotime < name[i-1].ptotime )
{
data tmp = name[i];
name[i] = name[i-1];
name[i-1] = tmp;
swapped = 1;
}
}
}
printf("Process Name\t Process Time \n");
for ( size_t i = 0; i < N; i++ )
{
printf( "\t%s\t\t\t\t%d\n", name[i].pname, name[i].ptotime );
}
return 0;
}
Its output is
Process Name Process Time
A 4
B 6
C 3
D 7
E 2
Shortest job first (SJF) scheduling
Process Name Process Time
E 2
C 3
A 4
B 6
D 7
Change:
for(int x = 0; x < 5; x++) {
into:
for(int x = 0; x < 4; x++) {
When x=4, the code compares name[4] with name[5], but name[5] is out of bounds (the only valid elements are name[0] ... name[4]).
There is a problem here:
for (int x = 0; x < 5; x++) {
if (name[x].ptotime >= name[x + 1].ptotime) {
the maximal value x can take is 4. But then name[x + 1] will access one element beyond the end of your array which has only 5 elements. Accessing an array out of bounds yields in undefined behaviour and all bets are off.
There may be more problems though.
In your swap cycle, this code snippet:
for(int x = 0; x < 5; x++)
In the last iteration you copy the values of name[4+1] to name[4] witch is to say you copy the values of the 6th element of your 5 element array, this is access out of bounds witch is undefined behavior.
Use
for(int x = 0; x < 4; x++)
This way the last cycle will be copying name[3+1] to name[3], 5th element to 4th element, witch is the expected behaviour.
Corrected code

why is this else block executed twice?

I have the following code which correctly calculates the jaccard similarity between an input char array and an existing array of char arrays. jacc_sim_rec[] is used to record the similarities which satisfy a minimum threshold value. The for loop is used to iterate through the multidimensional array and the loop is supposed to continue checking similarity if minimum threshold is not satisfied at if (jacc_sim < SIM_THRESHOLD); else record the result at
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
my problem is, the whole statements in the else block is executed twice every time the threshold value is satisfied.
int j=0;
void calc_jac_sim( char*INCOMING, int grp)
{
unsigned long i, j11 = 0, j01 = 0, j10 = 0,m=0;
char *m11, *m01, *m10;
float jacc_sim = 0.0;
char r1[SBF_LEN] = { NULL };
char r2[SBF_LEN] = { NULL };
char r3[SBF_LEN] = { NULL };
int cnt = SBF_LEN - 1;
clear_jacc_sim_info();
for (int i = 0; i <= SBF_REC[grp]; ++i)
{
while (cnt >= 0)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
cnt--;
}
m11 = ( char*)r1;
m01 = ( char*)r2;
m10 = ( char*)r3;
for (m = SBF_LEN * sizeof( char); m--;
j11 += NumberOfSetBits(*m11++),
j01 += NumberOfSetBits(*m01++),
j10 += NumberOfSetBits(*m10++));
jacc_sim = j11 / (float)(j11 + j01 + j10);
if (jacc_sim < SIM_THRESHOLD);
//continue;//do nothing
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
}
}
I don't understand the code, but I'll bet the problem is that you're not reinitializing cnt each time through the for loop, so you only fill in r1, r2, and r3 when i = 0.
Change that loop to:
for (int cnt = SBF_LEN - 1; cnt >= 0; cnt--)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
}
I'm also not sure why this needs to count down instead of up, like a typical loop, but it shouldn't make a difference.

Connect-N Board Game, crashing when Width is >> Height

I'm in the process of coding a Connect-N board game, and I'm almost finished and have gone through troubleshooting. My problem is now after changing some stuff my game crashes when the computer plays its move if the Width is too much greater than the height. There are two functions involved here, so I will paste them both.
Board
*AllocateBoard(int columns, int rows)
{
int **array= malloc(sizeof(int *) *columns);
int r = 0;
for ( r = 0; r < columns; ++r)
{
array[r] = malloc(sizeof(int) * rows);
}
int j = columns - 1;
int k = rows - 1;
int m = 0;
int n = 0;
for ( m = 0; m < j; ++m)
{
for ( n = 0; n < k; ++n)
{
array[m][n] = 0;
}
}
Board *board = malloc(sizeof(Board));
board->columns = columns;
board->rows = rows;
board->spaces = array;
return board;
}
This first function allocates the board to be a matrix Width * Height that the user passes in via the command line. It then initializes every space on the board to be zero, and then stores the columns, rows, and spaces into a Board structure that I've created. It then returns the board.
int
computerMakeMove(Board *board)
{ int RandIndex = 0;
int **spaces = board->spaces;
int columns = board->columns;
int *arrayoflegalmoves = malloc(sizeof(int) * (columns));
int columncheck = 0;
int legalmoveindex = 0;
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
}
if (legalmoveindex == 1)
{
return arrayoflegalmoves[0];
}
else
{
RandIndex = rand() % (legalmoveindex);
return arrayoflegalmoves[RandIndex];
}
}
This second function is designed to make the computer randomly pick a column on the board. It does this by checking the value of the top row in each column. If there is a zero there, it will store this value in an array of legal moves, and then it increments the legalmoveindex. If there isn't, it skips the column and checks the next. It ends when it gets finished checking the final column. If there is only one legal move, it will play it. If there are more, it will select a random index from the array of legal moves (I run srand in the main) and then return that value. It will only ever attempt to play on a legal board, so that's not the problem. I am pretty confident the problem occurs in this function, however, as I call the functions as follows
printf("Taking the computers move.\n");
{printf("Taking computer's move.");
computermove = computerMakeMove(playerboard);
printf("Computer's move successfully taken.\n");
playerboard = MakeMove(playerboard, computermove, player);
printf("Computer's board piece successfully played.\n");
system("clear");
displayBoard(playerboard);
...;
}
and it prints
Aborted (core dumped)
immediately after it prints
"Taking computer's move."
Once again, my question is: why is my program crashing if the width is larger than the height when the computer plays?
Thanks.
Edit: I found the solution and I am stupid.
I realloc'd during the while loop.
The realloc should be the first thing outside of the while loop.
The answer for any future programmers who may have this problem:
Notice the
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
}
has a realloc inside of it. The realloc should be moved to immediately outside of it, like so
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
it is unusual to have the columns be the first index in an array.
having the first index of an array be columns leads to confusion
// suggest using camel case for all variable names, for readability
Board *AllocateBoard(int columns, int rows)
{
int **array= malloc(sizeof(int *) *columns); // add check that malloc successful
int r = 0;
for ( r = 0; r < columns; ++r)
{
array[r] = malloc(sizeof(int) * rows); // <-- add: check that malloc successful
}
int j = columns - 1; // this results in last column not initialized
int k = rows - 1; // this results in last row of each column not initialized
int m = 0; // column loop counter
int n = 0; // row loop counter
for ( m = 0; m < j; ++m)
{
for ( n = 0; n < k; ++n)
{
array[m][n] = 0;
}
}
Board *board = malloc(sizeof(Board)); // <-- add: check if malloc successful
board->columns = columns;
board->rows = rows;
board->spaces = array;
return board;
} // end function: AllocateBoard
// why is this only looking at the first row of each column?
int computerMakeMove(Board *board)
{
int RandIndex = 0;
int **spaces = board->spaces;
int columns = board->columns;
int *arrayoflegalmoves = malloc(sizeof(int) * (columns)); // <-- add check that malloc successful
int columncheck = 0;
int legalmoveindex = 0;
while (columncheck <= columns - 1)// should be: for(; columncheck < columns; columncheck++ )
{
if (spaces[columncheck][0] == 0)
{ // then first row of column is zero
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck; // <-- remove this line
}
else // remove this 'else' code block
{
++columncheck;
} // end if
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
// <-- 1) use temp int*, in case realloc fails
// <-- 2) if realloc successful, update arrayoflegalmoves
// <-- 3) the code is not checking each row of each column,
// so the original malloc is more than plenty
// so why bother to realloc
// <-- 4) if legalmoveindex is 0 then realloc returns NULL
} // end while
// in following, what about when zero moves found? probably should return NULL
if (legalmoveindex == 1)
{ // only one column[row0] found to contain 0
return arrayoflegalmoves[0];
}
else
{
RandIndex = rand() % (legalmoveindex);
return arrayoflegalmoves[RandIndex]; // if zero moves found, this returns a
// de-reference to address 0
// which would result in a seg fault event
} // end if
} // end function: computerMakeMove

How do I calculate the row offset in a sparse matrix representation?

I'm writing a SpMxV (sparse matrix vector multiplication) program where I store the sparse matrix in a CRS format and then carry out the operations. Here's a short introduction on the format.
I know how to acquire the val and col_index_array arrays:
for (row_idx = 0; row_idx < row_count; row_idx++) {
for (col_idx = 0; col_idx < column_count; col_idx++) {
if (sparse_matrix[row_idx][col_idx] != 0) {
val[i] = sparse_matrix[row_idx][col_idx];
col_idx_array[i] = col_idx;
i++;
}
}
}
But I got stuck at acquiring the row_ptr indexes. How do I actually calculate them?
We have
row_ptr[i + 1] - row_ptr[i] = number of values in row i
therefore we simply have to store the current number of entries i in row_ptr when we look at the next row:
for (row_idx = 0; row_idx < row_count; row_idx++) {
row_ptr[row_idx] = i;
/* other code ommited */
}
row_ptr[row_idx] = i; /* equivalent to row_ptr[row_count] = i;
* total number of entries
*/
Note that this assumes that your arrays are 0-indexed, whereas the introduction you've posted assumes 1-indexed arrays.
Taking your code would look something like this:
for (row_idx = 0; row_idx < row_count; row_idx++) {
for (col_idx = 0; col_idx < column_count; col_idx++) {
if (sparse_matrix[row_idx][col_idx] != 0) {
val[i] = sparse_matrix[row_idx][col_idx];
col_idx_array[i] = col_idx;
i++;
}
}
row_ptr[row_idx+1]=i;
}

Program loses memory references as it progresses

I have a project that consists of several processes running in different computers. It is similar to a "OS Simulator", mainly task scheduling and resource allocation.
There's a main process, "Platform" or "Server", that planifies/schedules the different processes that connect to it, by using a queue with the available processes that are ready to execute.
As time passes however, the pointers lose the memory address of some of them, or the reference to it, or the memory to which it points is either freed or just used for some other variable. This then leads to the process that's supposed to run just halting and waiting for the Platform to schedule it, which never happens because the element from the queue no longer references the process(which we handle with file descriptors). Is there anyway to prevent this from happening??
Here's the portion of the code where we think the problem is:
response = string_substring_from(response, sizeof(FREERESC));
char** data = string_split(response, COMA);
t_queue *temporaryQueue = queue_create();
t_scheduler_queue *queues = dictionary_get(levels_queues, data[0]);
pthread_mutex_lock(queues->mutex);
t_queue *anotherQueue = queue_create();
long o = 0;
if (queue_size(queues->character_queue) > 0)
{
log_info(log, "Mas de un personaje listo");
for (o = 0; o < queue_size(queues->character_queue); o++)
{
personaje_planificador *personajeEnLista = queue_pop(
queues->character_queue);
personaje_planificador *nuevoPersonaje = (personaje_planificador*) malloc(sizeof(personaje_planificador));
// long *hola = (long*) malloc(sizeof(long));
// memcpy(hola, &(personajeEnLista->fd), sizeof(long));
// nuevoPersonaje->fd = hola;
nuevoPersonaje->fd = personajeEnLista->fd;
nuevoPersonaje->nombre = string_from_format("%s", personajeEnLista->nombre);
queue_push(anotherQueue, nuevoPersonaje);
}
}
char** simbolos;
long j = 2;
t_dictionary *recursosDisponibles = dictionary_create();
for (j = 2; j < list_size(queues->simbolos) + 2; j++)
{
simbolos = string_split(data[j], DOSPUNTOS);
long *temporary = (long*) malloc(sizeof(long));
*temporary = atoi(simbolos[1]);
dictionary_put(recursosDisponibles, simbolos[0], temporary);
}
if (queue_size(queues->blocked_queue) > 0)
{
log_info(log, "Mas de un personaje bloqueado");
long i = 0;
long k = 0;
for (i = 0; i < queue_size(queues->blocked_queue); i++)
{
blocked_character *blockedCharacter = queue_pop(queues->blocked_queue);
for (k = 0; k < list_size(queues->simbolos); k++)
{
if (blockedCharacter->recurso == ((char*) list_get(queues->simbolos, k))[0])
{
if (giveResource(queues, dictionary_get(recursosDisponibles, list_get(queues->simbolos, k)), blockedCharacter) == 1)
{
personaje_planificador *nuevoPersonajeAgain = (personaje_planificador*) malloc(sizeof(personaje_planificador));
nuevoPersonajeAgain->fd =
blockedCharacter->personaje->fd;
nuevoPersonajeAgain->nombre = blockedCharacter->personaje->nombre;
queue_push(temporaryQueue, nuevoPersonajeAgain);
//TODO log
}
else
{
queue_push(queues->blocked_queue, blockedCharacter);
}
}
}
k = 0;
}
}
o = 0;
for (o = 0; o < queue_size(temporaryQueue); o++)
{
queue_push(anotherQueue, queue_pop(temporaryQueue));
}
queues->character_queue = anotherQueue;
pthread_mutex_unlock(queues->mutex);
t_level_address *addresses = (t_level_address*) dictionary_get(levelsMap, data[0]);
char **levelSocket = string_split(addresses->nivel, DOSPUNTOS);
long fdNivel = openSocketClient(levelSocket[1], levelSocket[0]);
sendMessage(fdNivel, stringRecursos(queues->simbolos, recursosDisponibles, atoi(data[1])));
free(recursosDisponibles);
log_info(log, "Liberar recursos.");
if (flagTerminoUnPersonaje == TRUE)
{
executeKoopa(niveles, levels_queues, orquestador_config);
}
Let me know if a portion of the code is unclear (it has some things written in Spanish), or if you need another part where you think the problem may be in.
Somebody mentioned "ValGrind" in one of the comments.
Try one of the products mentioned here: http://en.wikipedia.org/wiki/BoundsChecker
You should be able to find a free trial if not an outright free version. (it's been about 10 years since I regularly maintained other people's C and had to use Purify and Insure to hunt down this kind of aliasing and leaking)

Resources