I’m doing a homework that involves multiplying matrix using winthreads.
I’m a newbie in C, and this is all the code i have (i made it reading some threads in here).
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define M 3
#define K 3
#define N 3
#define NUMBER_OF_THREADS 9
int A[M][K] = { {1,4,3}, {2,5,4}, {3,6,1} };
int B[K][N] = { {8,7,6}, {5,4,3}, {7,3,1} };
int C[M][N];
clock_t start,end;
struct v
{
int i;
int j;
};
DWORD WINAPI MatrixMult(LPVOID Param)
{
int a;
DWORD sum = 0;
struct v *data = Param;
for(a = 0; a < 3; a++)
{
sum = sum + ((A[data->i][a]) * (B[a][data->j]));
}
C[data->i][data->j] = sum;
return 0;
}
int main()
{
struct v *data = malloc(sizeof(struct v));
int i, j, k;
DWORD ThreadIds[NUMBER_OF_THREADS];
HANDLE ThreadHandles[NUMBER_OF_THREADS];
int thread_index = 0;
start = clock();
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++ )
{
data->i = i;
data->j = j;
ThreadHandles[thread_index] = CreateThread (NULL, 0, MatrixMult, &data, 0, &ThreadIds[thread_index]);
if (!ThreadHandles)
{
printf("Error, threads cannot be created");
return 1;
}
}
thread_index++;
}
printf("Result:\n");
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++)
{
printf("C[%d][%d] = %f\n", i,j, C[i][j]);
}
}
for (i = 0; i < 9; i++)
{
CloseHandle(ThreadHandles[i]);
}
end = clock();
printf("Tiempo = %d", end - start);
return 0;
}
I’m having some problems with this program, it compiles, but it doesn’t run, it marks an error in 0x775f15de exception, error in reading 0x3468a3bc. Any ideas why this error is present and how can I fix it?
There are (at least) three problems:
datais astruct v*but it’s address is being passed as the argument to the thread (i.e. astruct v**) which is then being interpreted as astruct v*. This is incorrect and is a probable cause of the error.All threads will be executing on the same instance of
struct vnameddata. This will introduce race conditions. Allocate a newstruct vfor each thread and have the threadfree()it when no longer required.The type of
C[i][j]is anintbut theprintf()has the format specifier%f. This is incorrect, it should be%d(as it is for the other arguments).Note that it is not required to cast the return value of
malloc()( Do I cast the result of malloc? ). A more common and better way of writing themalloc()line from the posted code is:Remember to
free()what ismalloc()d.