0

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?

Bernardo Ortiz
  • 95
  • 1
  • 1
  • 9
  • 1
    Have you tried using the debugger? Learning how to use the debugger is a crucial skill in programming. – Adam Rosenfield Nov 16 '12 at 22:12
  • "Why the homework tag is being deprecated and is going to be deleted? I think it is useful." - People smarter than you/having more experience on SO think it isn't, that's why. –  Nov 16 '12 at 22:15
  • Also, you **must** pay attention to using whitespaces and indentation correctly; furhtermore `void *` **should not** be cast, since it's implicitly compatible with any data pointer type - and the only effect of casting is decreasing readability. –  Nov 16 '12 at 22:22
  • 2
    I think the reason for removing the tag is because it's not a useful tag to describe a question. It's a "meta" tag that could apply to anything. Ultimately, whether a question is good does not depend on whether it's for homework. Homework doesn't excuse writing a poor question, and a good question does not need to be explained as homework even if it is. – Kerrek SB Nov 16 '12 at 22:24
  • @KerrekSB Very consise and valid reasoning. +1. –  Nov 16 '12 at 22:25
  • I think you need to define the thread count as M*N. And don't hard code the 3 in the thread proc. – David Heffernan Nov 16 '12 at 22:37

1 Answers1

2

There are (at least) three problems:

  1. data is a struct v* but it's address is being passed as the argument to the thread (i.e. a struct v**) which is then being interpreted as a struct v*. This is incorrect and is a probable cause of the error.

  2. All threads will be executing on the same instance of struct v named data. This will introduce race conditions. Allocate a new struct v for each thread and have the thread free() it when no longer required.

  3. The type of C[i][j] is an int but the printf() 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 the malloc() line from the posted code is:

struct v* data = malloc(sizeof(*data));

Remember to free() what is malloc()d.

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • Hi, thanks for responding =). I discovered that the ThreadHandles is ginving the error, when j=2 or more, the error shows. Wonder if it's the declaration of the struct. – Bernardo Ortiz Nov 16 '12 at 22:39
  • Hi, thanks for responding =). I discovered that the ThreadHandles is ginving the error, when j=2 or more, the error shows. Wonder if it's the declaration of the struct. I changed it, like it was suggested and it marks error on the malloc, it says that a void data can't be used to initialize an entity type v. – Bernardo Ortiz Nov 16 '12 at 22:56
  • @BernardoOrtiz, what is suffix of your source file? A `void*` can be implicitly assigned to any pointer type in C. This is not true in C++. – hmjd Nov 16 '12 at 22:58
  • suffix of file? hmm ... it's .c, why? – Bernardo Ortiz Nov 16 '12 at 23:12