I've wrote the following code to implement matrix multiplication but repeatedly i got segmentation fault error. It's seems to everything be OK. can anybody tell my what's the problem.
this is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int matrixSize;
double ** a, ** b, ** c;
typedef struct tparms {
int row;
int col;
}tparms_t;
double ** allocateMatrix() {
int i;
double *vals, **temp;
//allocate values
vals = (double *) malloc (matrixSize * matrixSize * sizeof(double));
// allocate vector of pointers
temp = (double **) malloc (matrixSize * sizeof(double*));
for(i=0; i < matrixSize; i++)
temp[i] = &(vals[i * matrixSize]);
return temp;
}
void* multiply (void* _arg){
tparms_t * arg = (tparms_t *) _arg;
int i;
double sum;
for (i=0; i<matrixSize; i++)
sum += a[arg->row][i] * b[i][arg->col];
c[arg->row][arg->col] = sum;
}
void main(int argc, char *argv[]) {
pthread_t *threads;
if (argc != 2) {
printf("Usage: %s <size>, where size is dimension of square matrix\n", argv[0]);
exit(1);
}
int matrixSize = atoi(argv[1]);
threads = (pthread_t *) malloc(matrixSize * matrixSize * sizeof(pthread_t));
a = allocateMatrix();
b = allocateMatrix();
c = allocateMatrix();
int i, j;
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
a[i][j] = i + j;
b[i][j] = i + j;
}
}
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
tparms_t * tt = (tparms_t *)malloc(sizeof(tparms_t));
tt->row = i;
tt->col = j;
pthread_create(&threads[i*matrixSize + j], NULL, multiply, (void*)tt);
}
}
// two for for arrays
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
//do something ...
pthread_join(threads[i*matrixSize+j], NULL);
}
}
// end of two fors
}
there is a struct to pass data to threads, allocation function to allocate arrays and in main function i decide to create a thread for each of matrix elements. then a join function to wait until all threads do their job and create the c matrix elements.
You have int matrixSize = atoi (argv[1] );. Remove int because that creates another local instance of matrixSize.
Related
I am trying to initialize an arary using a function but I feel like theres something not right about it. When I compile it I am getting Segmentation Fault but not sure where about. Can someone point me in the right direction where I got wrong. I mean if theres a better way to do it feel free to comment.
Thank you.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void initialize(int ** arr, int row, int col)
{
int i;
arr = (int **) malloc(sizeof(int *) *col);
for(i = 0; i < row; i++)
{
arr[i] = (int *) malloc(sizeof(int) * row);
}
}
void freeArray(int ** arr)
{
free(arr);
}
int main()
{
int **arr;
int r, c;
initialize(arr, 3,6);
for(r = 0; r <= 3; r++)
{
for(c = 0; c <= 6; c++)
{
printf("%d ", arr[r][c] = r*c);
}
printf("\n");
}
freeArray(arr);
}
For starters the function has a bug.
void initialize(int ** arr, int row, int col)
{
int i;
arr = (int **) malloc(sizeof(int *) *col);
for(i = 0; i < row; i++)
{
arr[i] = (int *) malloc(sizeof(int) * row);
}
}
Instead of using the variable col in this statement
arr = (int **) malloc(sizeof(int *) *col);
you have to use the variable row
arr = (int **) malloc(sizeof(int *) *row);
And in this statement instead of using the variable row
arr[i] = (int *) malloc(sizeof(int) * row);
you have to use the variable col
arr[i] = (int *) malloc(sizeof(int) * col);
As for the main problem then the function accepts the pointer declared in main by value. It means that the function deals with a copy of the pointer. Changes of the copy do not reflect on the original pointer.
Either you need to pass the pointer to the function indirectly through a pointer to it (passing by reference) like
void initialize(int *** arr, int row, int col)
{
int i;
*arr = (int **) malloc(sizeof(int *) *row);
for(i = 0; i < row; i++)
{
( *arr )[i] = (int *) malloc(sizeof(int) * col);
}
}
and the function is called like
initialize( &arr, 3,6);
Or it is better when the function allocates arrays and returns a pointer to the arrays like
int ** initialize( int row, int col)
{
int **arr;
arr = (int **) malloc(sizeof(int *) *row);
for( int i = 0; i < row; i++)
{
arr[i] = (int *) malloc(sizeof(int) * col);
}
return arr;
}
and the function is called like
int **arr = initialize( 3, 6 );
Also in the nested for loops in main there are used invalid conditions
for(r = 0; r <= 3; r++)
{
for(c = 0; c <= 6; c++)
{
printf("%d ", arr[r][c] = r*c);
}
printf("\n");
}
You have to write
for(r = 0; r < 3; r++)
{
for(c = 0; c < 6; c++)
{
printf("%d ", arr[r][c] = r*c);
}
printf("\n");
}
Also the function freeArray must be declared and defined the following way
void freeArray(int ** arr, int row)
{
if ( arr != NULL )
{
for ( int i = 0; i < row; i++ )
{
free( arr[i] );
}
}
free( arr );
}
and called like
freeArray(arr, 3);
Pay attention to that in general you need to check whether memory was successfully allocated before using pointers that point to dynamically allocated memory.
I have to create in C a program that is able to calculate the determinant of a random 3x3 matrix using the Sarrus method. I have to use one thread (Thread A) to compute blue diagonals, and a second thread (Thread B) to compute red ones. (See img https://i.stack.imgur.com/HQL1U.png )
My code is:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define m 3
#define n 3
typedef struct thread_params{
int *data_matrix;
int diag_result;
} thread_params;
void *diagA (void *params){
thread_params *pp = (thread_params *) params;
int **matrix_ptr = &pp->data_matrix;
int diag = 0;
diag = matrix_ptr[0][0] * matrix_ptr[1][1] * matrix_ptr[2][2] + matrix_ptr[0][1] * matrix_ptr[1][2] * matrix_ptr[2][0] + matrix_ptr[0][2] * matrix_ptr[1][0] * matrix_ptr[2][1];
pp->diag_result = diag;
return (void *) &pp->diag_result;
}
void *diagB (void *params){
thread_params *pp = (thread_params *) params;
int **matrix_ptr = &pp->data_matrix;
int diag = 0;
diag = matrix_ptr[2][0] * matrix_ptr[1][1] * matrix_ptr[0][2] + matrix_ptr[2][1] * matrix_ptr[1][2] * matrix_ptr[0][0] + matrix_ptr[2][2] * matrix_ptr[1][0] * matrix_ptr[0][1];
pp->diag_result = diag;
return (void *) &pp->diag_result;
}
int main(){
// Create matrix
int **matrix;
int row;
matrix = (int **) malloc(m * sizeof(int *));
for (row = 0; row < m; row++){
matrix[row] = (int *) malloc(n * sizeof(int));
}
// Matrix initialization
srand(time(NULL));
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
matrix[i][j] = rand() % 10;
printf("%d ", matrix[i][j]);
}printf("\n");
}
// Thread creation
pthread_t threadA_id;
pthread_t threadB_id;
int *threadA_returnValue;
int *threadB_returnValue;
thread_params threadA_args;
thread_params threadB_args;
threadA_args.data_matrix = &matrix[0][0];
threadA_args.diag_result = 0;
threadB_args.data_matrix = &matrix[0][0];
threadB_args.diag_result = 0;
pthread_create(&threadA_id, NULL, &diagA, &threadA_args);
pthread_create(&threadB_id, NULL, &diagB, &threadB_args);
pthread_join(threadA_id, (void **) &threadA_returnValue);
pthread_join(threadB_id, (void **) &threadB_returnValue);
// Print results
printf("%d - %d = %d\n", *threadA_returnValue, *threadB_returnValue, *threadA_returnValue - *threadB_returnValue);
return 0;
}
The main problem is that I don't know how to correctly send the random matrix as argument to the threads functions. I tried to utilize a struct with a pointer inside but in this way I'm able to sent to the thread function only the first row of my matrix and then, when I try to access the second row, a segmentation fault error is generated.
I think my error is caused by this type of assignation:
threadA_args.data_matrix = &matrix[0][0];
How can I solve this problem?
I'm making a program which dynamically creating 2d array.but it's showing the error which I mentioned on the title. I'm using Visual Studio 2015.
// last.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include "stdlib.h"
double selectionSort(int * number, int number_count);
void print2d(int ** array, int rows, int cols);
void twodarray();
void main(int argc, char* argv[])
{
int num_count = 10000;
int num[10000];
for (int i = 0; i < num_count; i++)
{
num[i] = rand();
}
double sortTime = selectionSort(num, num_count);
printf("Total Runtime is: %.0f milliseconds. \n", sortTime * 1000);
twodarray();
getchar();
}
double selectionSort(int * number, int number_count)
{
clock_t start, end;
double duration;
int min;
start = clock();
for (int i = 0; i < number_count - 1; i++)
{
min = i;
for (int j = i + 1; j < number_count; j++)
{
if (number[min] > number[j])
{
min = j;
}
}
if (min != i)
{
int temp = number[min];
number[min] = number[i];
number[i] = temp;
}
}
end = clock();
return duration = (double)(end - start) / CLOCKS_PER_SEC;
}
void print2d(int ** array, int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0, j < cols; j++;)
{
printf("%10d ", array[i][j]);
}
puts("");
}
}
void twodarray()
{
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
int i,cols = 10;
for (i = 0; i < rows; i++)
{
twod[i] = malloc(cols*sizeof(int));
print2d(twod, rows, cols);
}
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod);
}
}
In c++ you need to cast when assigining a void * pointer to another type of pointer. But in c++ you should not use malloc(), instead use
int **twod = new int *[rows];
If you didn't mean to write a c++ program, rename the file. Change the extension from .cpp to .c.
Your allocation is wrong too, as pointed out by #KeineLust here.
This is wrong:
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
You need to reserve space for n pointers to int, not for n ints, change to
twod = malloc(rows * sizeof(int *));
And here:
for (j = 0, j < cols; j++;)
^ ^
Use a semicolon instead of a comma and also remove the last semicolon.
Another problem:
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod); /* Don't free twod in the loop, one malloc -> one free */
}
And as pointed out by Nicat and Iharob, it seems that you are mixing C and C++, use the proper extension (.c)
I have this code for allocating a float matrix on runtime:
float **create_matrix(int w, int h) {
// alocates the matrix rows first
float **matrix = (float**)malloc(h * sizeof(float*));
// now allocates and populates each line
for (int i = 0; i < h; i++) {
matrix[i] = (float*) malloc(w * sizeof(float));
// sample matrix filling
for (int j = 0; j < w; j++)
matrix[i][j] = (i + 1) * (j + 1);
}
return matrix;
}
It seems to be working fine, since it doesn't crash and when I display the matrix I have the very same values that I initialized it. Although when I try to free the matrix, iff the number of rows is lesser than the number of columns, I receive the following error message:
a.out(14284,0x7fff73cc9300) malloc: * error for object 0x9000000000000000: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug. Abort trap: 6"
My freeing routine follows:
void free_matrix(float **matrix, int h) {
for (int i = 0; i < h; i++)
free(matrix[i]);
free(matrix);
}
Try this
#include <stdio.h>
#include <stdlib.h>
float **create_matrix(int h, int w)
{
float **matrix = (float **)malloc(h*sizeof(float *));
int i,j;
for(i=0;i<h;i++){
matrix[i] = (float *)malloc(w*sizeof(float));
}
for(i=0;i<h;i++){
for(j=0;j<w;j++){
matrix[i][j] = (i+1)*(j+1);
}
}
return matrix;
}
int main()
{
int h = 2, w = 3;
float **matrix = create_matrix(h,w);
int i,j;
for(i=0;i<h;i++){
for(j=0;j<w;j++){
printf("%.2f ",matrix[i][j]);
}
printf("\n");
}
return 0;
}
You need to allocate memory before you start making operations.
I was experimenting some basic C code that defines an int matrix with pointers.
typedef int **Matrix;
Matrix createMatrix(int lines, int columns) {
int i, j;
Matrix m = (Matrix) malloc(sizeof(int) * lines * columns);
for (i = 0; i < lines; ++i) {
for (j = 0; j < columns; ++j) {
m[i][j] = 0;
}
}
return m;
}
int main(int argc, char**argv) {
Matrix m = createMatrix(5, 10);
// ...
if (m[2][3] == 20) {
// ...
}
return 0;
}
However, these m[i][j] accesses are throwing segmentation faults. What's wrong here? Too many asterisks?
I was convinced that a pointer to a pointer to an int was effectively the same as a matrix.
Your allocation of the Matrix data item assumes you're accessing it linearly with a single index. If you want to access it with two indices, e.g., m[1][1] you need to allocate each dimension:
Matrix m = malloc(sizeof(int *) * lines);
for ( int i = 0; i < lines; i++ )
m[i] = malloc(sizeof(int) * columns);
Note also that you should not type cast malloc.