I need to create a program that gets a dynamic matrix and changes it to one dimension, for example 4x4 matrix will give 16 arrays length, where each index has a odd or even number, matching the index itself. The threads needs to go over the matrix at the same time and copy the odd and even numbers to the correct places in the array. The main thread needs to wait for the rest of them to finish before printing the array and every value with its respective thread. It should come out like this
We managed to fix the segmentation fault that kept happening, but now we need to set it so that each thread runs right after the other but instead each thread runs 4 times and then it switches to a different one. How can I change it so it'll run as asked?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#define CORE 4
int N;
int odd = 1;
int even = 0;
typedef struct my_thread {
int** matrix;
int* resArray;
int threadId;
int strart_raw;
int strart_cal;
int end_raw;
int end_cal;
int counter;
} my_thread;
void* createArray(struct my_thread* thread);
void main() {
pthread_t th[CORE];
int s_r = 0, s_c, e_r, e_c;
int i, j, lines, columns, * intMatrix;
printf("Type the N for the N*N matrix:\t");
scanf("%d", &N);
int size = N * N;
int result_Array[N * N];
int retcode;
int interval = size / CORE;
int matrix_build_counter = 1;
intMatrix = (int*)malloc(N * N * sizeof(int));
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; ++j)
{
intMatrix[i * N + j] = matrix_build_counter;
matrix_build_counter++;
}
}
printf("The matrix:\n");
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%d ", intMatrix[i * N + j]);
}
printf("\n");
}
struct my_thread thred_obj_array[CORE];
for (int i = 0; i < CORE; i++) {
thred_obj_array[i].matrix = &intMatrix;
thred_obj_array[i].resArray = result_Array;
thred_obj_array[i].threadId = i;
thred_obj_array[i].strart_raw = (int)((i * N) / CORE);
thred_obj_array[i].end_raw = (int)(((interval * (i + 1)) / N));
thred_obj_array[i].strart_cal = ((interval * i)) % N;
thred_obj_array[i].end_cal = ((interval) * (i + 1));
thred_obj_array[i].counter = (int)floor((interval)*i);
}
for (int i = 0; i < CORE; i++) {
retcode = pthread_create(&th[i], NULL, createArray, &thred_obj_array[i]);
if (retcode != 0) {
printf("Create thread failed with error %d\n", retcode);
}
}
printf("done");
for (int i = 0; i < CORE; i++) {
pthread_join(th[i], NULL);
}
printf("the result array is: ");
for (int i = 0; i < N * N; i++) {
printf("%d ", result_Array[i]);
}
}
void* createArray(struct my_thread* thread) {
int j;
for (int i = thread->strart_raw; i < N; i = i * sizeof(int) * N) {
for (j = thread->strart_cal; j < N; j++) {
printf("I am thread: %d And my value is: %d , (%d,%d)\n", thread->threadId, (*thread->matrix + i * N)[j], i, j);
if (((*thread->matrix + i * N)[j]) % 2 == 0) {
thread->resArray[even] = (*thread->matrix + i * N)[j];
even += 2;
printf("-----%d ---even---\n", even);
}
else {
thread->resArray[odd] = (*thread->matrix + i * N)[j];
odd += 2;
printf("---%d ---odd--\n", odd);
}
(thread->counter)++;
if (thread->counter == thread->end_cal) {
return;
}
}
thread->strart_cal = 0;
}
}
Related
This program takes an integer from input and populates a double array with random values and creates threads to sort each half of the array, one thread to sort the entire array, one to sort the first half, and one to sort the second half but segfaults at pthread_create(&tid1, NULL, selectionSortFirstHalf, A_First_Half). I added multiple print statements as shown below and also used gdb to confirm where the seg fault is but I'm completely lost as to why it doesn't work for array sizes greater than 4.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
typedef struct merge
{
double *FirstHalf;
double *SecondHalf;
double *myVal;
} MergeArray;
// Global Vars
int ArraySize;
int ArrayHalfSize;
void *mergeThread(void *args)
{
int i, j;
MergeArray *myMerge = (struct merge *)args;
for(i = 0; i < ArrayHalfSize; i++)
{
myMerge->myVal[i] = myMerge->FirstHalf[i];
}
ArraySize = ArrayHalfSize + ArrayHalfSize;
for(i = 0, j = ArrayHalfSize; j < ArraySize && i < ArrayHalfSize; i++, j++)
{
myMerge->myVal[j] = myMerge->SecondHalf[i];
}
return NULL;
}
void *selectionSortThreadB(void *args)
{
double *arr;
double *ptrArr;
arr = (double*)args;
ptrArr = (double*)malloc(ArraySize * sizeof(double));
int i;
int j;
double temp;
for(i = 1; i < ArraySize; i++)
{
temp = arr[i];
j = i - 1;
while(j >= 0 && arr[j] > temp)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = temp;
}
/*for(i = 0; i < ArraySize; i++)
{
printf("SSTB: %d, %.2lf\n", i, arr[i]);
}*/
ptrArr = arr;
pthread_exit((void*)ptrArr);
}
void *selectionSortSecondHalf(void *args)
{
double *myarr, *myptrretSecondHalf;
myarr = (double *)args;
myptrretSecondHalf = (double *)malloc(ArrayHalfSize * sizeof(double));
if(myptrretSecondHalf == NULL)
{
fprintf(stderr, "Could not allocate memory in selectionSortSecondtHalf\n");
exit(-1);
}
int i, j;
int min;
double temp;
/*for(i = ArrayHalfSize; i < ArraySize; i++)
{
printf("This is the second half of the array when passed to SSSH: A_Second_Half[%d] = %.2lf\n", i, myarr[i]);
}*/
for (i = ArrayHalfSize; i < ArraySize; i++)
{
min = i;
for(j = i + 1; j < ArraySize; j++)
{
if(myarr[j] < myarr[min])
min = j;
}
temp = myarr[i];
myarr[i] = myarr[min];
myarr[min] = temp;
}
myptrretSecondHalf = myarr;
pthread_exit(myptrretSecondHalf);
}
void *selectionSortFirstHalf(void *args)
{
//printf("hello from 104\n");
double *myarr, *myptrretFirstHalf;
myarr = (double *)args;
myptrretFirstHalf = (double *)malloc(ArrayHalfSize * sizeof(double));
if(myptrretFirstHalf == NULL)
{
fprintf(stderr, "Could not allocate memory in selectionSortFirstHalf\n");
exit(-1);
}
int i, j;
int min;
double temp;
/*for(i = 0; i < ArrayHalfSize; i++)
{
printf("This is the first half of the array when passed to SSFH: A_First_Half[%d] = %.2lf\n", i, myarr[i]);
}*/
for (i = 0; i < ArrayHalfSize; i++)
{
min = i;
for(j = i + 1; j < ArrayHalfSize; j++)
{
if(myarr[j] < myarr[min])
min = j;
}
temp = myarr[i];
myarr[i] = myarr[min];
myarr[min] = temp;
}
myptrretFirstHalf = myarr;
pthread_exit(myptrretFirstHalf);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
fprintf(stderr, "ERROR: Please provide the correct number of arguments (file, size of array)\n");
exit(-1);
}
else
{
ArraySize = atoi(argv[1]);
ArrayHalfSize = (ArraySize / 2);
clock_t start, end, start2, end2;
double RandomNum;
double *ThreadBlock;
double *ThreadArrayHalf1;
double *ThreadArrayHalf2;
pthread_t tid, tid1, tid2, tid3;
double A[ArraySize];
double B[ArraySize];
//double C[ArraySize];
double *A_First_Half/*[ArrayHalfSize]*/;
double *A_Second_Half/*[ArrayHalfSize]*/;
A_First_Half = (double*)malloc(sizeof(A_First_Half)*ArrayHalfSize);
A_Second_Half = (double*)malloc(sizeof(A_Second_Half)*ArrayHalfSize);
int i;
srand(time(NULL)); // generate seed for rand nums based on time
for(i = 0; i < ArraySize; i++)
{
RandomNum = ((double) rand()*(1000.0+1.0)/(double)RAND_MAX+1.0);
printf("%.2lf\n", RandomNum);
A[i] = RandomNum;
}
for(i = 0; i < ArraySize; i++)
{
B[i] = A[i];
}
start = clock();
pthread_create(&tid, NULL, selectionSortThreadB, (void*)B);
pthread_join(tid, (void**)&ThreadBlock);
end = clock() - start;
printf("Sorting is done in %.2fms when one thread is used\n", end * 1000.0 / CLOCKS_PER_SEC);
//*******Two-Threaded Option**************//
// prints A[]
for(i = 0; i < ArraySize; i++)
{
printf("A[%d] = %.2lf\n", i, A[i]);
}
// populates first half of array A with half of A
for(i = 0; i < ArrayHalfSize; i++)
{
A_First_Half[i] = A[i];
printf("A_First_Half[%d] = %.2lf\n", i, A_First_Half[i]);
}
// populates second half of array A with second half of B
for(i = ArrayHalfSize; i < ArraySize; i++)
{
A_Second_Half[i] = A[i];
printf("A_Second_Half[%d] = %.2lf\n", i, A_Second_Half[i]);
}
printf("hello from 199\n");
start2 = clock();
printf("hello from 201\n");
pthread_create(&tid1, NULL, selectionSortFirstHalf, A_First_Half);
printf("hello from 203\n");
pthread_create(&tid2, NULL, selectionSortSecondHalf, A_Second_Half);
printf("hello from 205\n");
pthread_join(tid1, (void**)&ThreadArrayHalf1);
pthread_join(tid2, (void**)&ThreadArrayHalf2);
MergeArray threadMerge;
threadMerge.myVal = (double*)malloc(ArraySize * sizeof(double));
for(i = 0; i < ArrayHalfSize; i++)
{
printf("SSFH: %d, %.2lf\n", i, ThreadArrayHalf1[i]);
}
for(i = ArrayHalfSize; i < ArraySize; i++)
{
printf("SSSH: %d, %.2lf\n", i, ThreadArrayHalf2[i]);
}
threadMerge.FirstHalf = ThreadArrayHalf1;
threadMerge.SecondHalf = ThreadArrayHalf2;
pthread_create(&tid3, NULL, mergeThread, (void*)&threadMerge);
pthread_join(tid3, NULL);
end2 = clock() - start2;
printf("Sorting is done in %.2fms when two threads are used\n", end2 * 1000.0 / CLOCKS_PER_SEC);
//free(A_First_Half);
//free(A_Second_Half);
//free(threadMerge.myVal);
}
return 0;
}
A_First_Half = (double*)malloc(sizeof(A_First_Half)*ArrayHalfSize); allocates space based on sizeof(A_First_Half), which uses the size of the pointer A_First_Half, not the size of the object it points to, *A_First_Half.
And you do not need the parentheses for sizeof with an expression or the cast of malloc. So use A_First_Half = malloc(sizeof *A_First_Half * ArrayHalfSize);.
In several places, a “second half” array is used with indices running from ArrayHalfSize to ArraySize-1. However, they point to storage for which space for ArrayHalfSize elements has been allocated. Indices in that space run from 0 to ArrayHalfSize-1. All the code should be changed to use only indices from 0 to ArrayHalfSize-1 with these “second halves.”
Along those lines, there is no need for selectionSortFirstHalf and selectionSortSecondHalf to be separate routines. Once selectionSortSecondHalf is fixed, per above, it will do the same thing as selectionSortFirstHalf: Sort an array with ArrayHalfSize elements.
Once you have fixed those and gotten the program working, eliminate the global variables and pass all the necessary information to the threads via their argument pointer (by pointing to a structure that contains the information the thread needs).
So, this is my program that calculates matrix determinant using system calls, not good at all, but, the trouble is that when i put in a number bigger than 8 for dimension of matrix, it crashes somehow and i can't figure why it keeps happening. Please, give me some ideas.
The task was to calculate determinant using multithreading. Maybe, the problem is that I exceed max threads? valgrind says that
Use --max-threads=INT to specify a larger number of threads
and rerun valgrind
valgrind: the 'impossible' happened:
Max number of threads is too low
compile it with gcc -g -pthread
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <time.h>
#include <malloc.h>
pthread_mutex_t mutex;
typedef struct {
int **matrix;
int size;
} T_MS;
void* determinant(void *npt) {
T_MS* tmp = (T_MS*) npt;
int i,j;
double det = 0;
pthread_t *array = malloc(sizeof(pthread_t) * tmp->size);
T_MS *mtarr = malloc(sizeof(T_MS) * tmp->size);
if (tmp->size == 1) {
det = tmp->matrix[0][0];
} else if (tmp->size == 2) {
det = tmp->matrix[0][0] * tmp->matrix[1][1] - tmp->matrix[0][1] * tmp->matrix[1][0];
} else {
for (i = 0; i < tmp->size; ++i) {
mtarr[i].matrix = (int **)malloc(sizeof(int *) * tmp->size);
mtarr[i].size = tmp->size - 1;
for (j = 0; j < tmp->size - 1; ++j) {
if (j < i)
mtarr[i].matrix[j] = tmp->matrix[j];
else
mtarr[i].matrix[j] = tmp->matrix[j + 1];
}
pthread_create(&array[i], NULL, determinant, mtarr + i);
}
for (i = 0; i < tmp->size; ++i) {
void *res;
for (j = 0; j < tmp->size - 1; ++j) {
}
pthread_join(array[i], &res);
double x = *(double *)&res;
det += (-1 + 2 * !(i % 2)) * x * tmp->matrix[i][tmp->size - 1];
double answer = *(double*)&det;
free(mtarr[i].matrix);
}
}
free(mtarr);
free(array);
void* ans = *(void **)&det;
return ans;
}
int main(int argc, char const *argv[]) {
srand(time(NULL));
int **matrix;
int n = 0;
int a;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
printf("Insert the demention of matrix:\n");
scanf("%d", &n);
matrix = (int**)malloc(n * sizeof(int*));
for (int i=0; i<n; ++i)
matrix[i] = (int*)malloc(n * sizeof(int));
printf("Insert matrix:\n");
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
matrix[i][j]=rand()%15;
//matrix[i][j] = i;
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
T_MS* npt = (T_MS*)malloc(sizeof(T_MS));
npt->matrix = matrix;
npt->size = n;
void *det;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, determinant, npt);
pthread_join(tid, &det);
double answer = *(double*)&det;
printf("Det is: %f\n", answer);
for (int i = 0; i < n; ++i)
free(matrix[i]);
free(matrix);
free(npt);
return 0;
} ```
How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));
In the function printprime, I am iterating over each element with each of the four threads, this is almost equivalent to a single threaded program. I want to increment i by i=i+MAX_THREADS. I am using four threads as my Laptop has four processors and it is fully optimized. Can someone tell me how to tweak the printprime so that each thread iterates over a single digit. Like, thread 1 checks 2, 6, 10... thread2 checks 3, 7, 11... and so on.
#include <stdio.h>
#include <pthread.h>
#define N 30
#define MAX_THREADS 4
int prime_arr[N] = { 0 };
void *printprime(void *ptr) {
int j, flag;
int i = (int)(long long int)ptr;
for (i = 2; i < N; i++) {
flag = 0;
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
prime_arr[i] = 1;
}
}
}
int main() {
pthread_t tid[MAX_THREADS] = {{ 0 }};
int count = 0;
for (count = 0; count < MAX_THREADS; count++) {
printf("\r\n CREATING THREADS %d", count);
pthread_create(&tid[count], NULL, printprime, (void *)count);
}
printf("\n");
for (count = 0; count < MAX_THREADS; count++) {
pthread_join(tid[count], NULL);
}
int c = 0;
for (count = 0; count < N; count++)
if (prime_arr[count] == 1)
printf("%d ", count);
return 0;
}
To achieve desirable, increment variable i in function void *printprime(void *ptr) by MAX_THREADS(4 in your case).
Note: Line printf("Thread id[%d] checking [%d]\n",pthread_self(),i); is used to show that which thread is checking which value.
Following code may be helpful:
#include<stdio.h>
#include<pthread.h>
#define N 30
#define MAX_THREADS 4
int prime_arr[N]={0};
void *printprime(void *ptr)
{
int j,flag;
int i=(int)(long long int)ptr;
while(i<N)
{
printf("Thread id[%d] checking [%d]\n",pthread_self(),i);
flag=0;
for(j=2;j<=i/2;j++)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(flag==0 && (i>1))
{
prime_arr[i]=1;
}
i+=MAX_THREADS;
}
}
int main()
{
pthread_t tid[MAX_THREADS]={{0}};
int count=0;
for(count=0;count<MAX_THREADS;count++)
{
printf("\r\n CREATING THREADS %d",count);
pthread_create(&tid[count],NULL,printprime,(void*)count);
}
printf("\n");
for(count=0;count<MAX_THREADS;count++)
{
pthread_join(tid[count],NULL);
}
int c=0;
for(count=0;count<N;count++)
if(prime_arr[count]==1)
printf("%d ",count);
return 0;
}
There are multiple problems in your code:
all threads use for (i = 2; i < N; i++) so they perform exactly the same scan, testing the same numbers... You get no advantage from using multiple threads.
the name printprime is very confusing for a function that scans for prime numbers but does not print them.
you modify the same array in multiple threads without synchronisation: this has undefined behavior if the same element is accessed from different threads and if the element size is smaller than the atomic size.
even if the code was modified for each thread to test the subset you document in the question, this would be very inefficient as every other threads would end up testing only even numbers.
the loop for (j = 2; j <= i / 2; j++) iterates far too long for prime numbers. You should stop when j * j > i, which can be tested as for (j = 2; i / j <= j; j++).
even with this optimisation, trial division is very inefficient to populate the prime_arr array. Implementing a Sieve of Eratosthenes is far superior and much more appropriate for a multithreading approach.
Here is an example:
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#define N 10000000
#define MAX_THREADS 4
unsigned char prime_arr[N];
void *scanprime(void *ptr) {
int n, i, j, flag, start, stop;
n = (int)(intptr_t)ptr;
start = N / MAX_THREADS * n;
stop = N / MAX_THREADS * (n + 1);
if (start < 2)
start = 2;
if (n == MAX_THREADS - 1)
stop = N;
for (i = start; i < stop; i++) {
flag = 1;
for (j = 2; i / j >= j; j++) {
if (i % j == 0) {
flag = 0;
break;
}
}
prime_arr[i] = flag;
}
return NULL;
}
void *sieveprimes(void *ptr) {
int n, i, j, start, stop;
n = (int)(intptr_t)ptr;
/* compute slice boundaries */
start = N / MAX_THREADS * n;
stop = N / MAX_THREADS * (n + 1);
/* special case 0, 1 and 2 */
if (n == 0) {
prime_arr[0] = prime_arr[1] = 0;
prime_arr[2] = 1;
start = 3;
}
if (n == MAX_THREADS - 1) {
stop = N;
}
/* initialize array slice: only odd numbers may be prime */
for (i = start; i < stop; i++) {
prime_arr[i] = i & 1;
}
/* set all multiples of odd numbers as composite */
for (j = 3; j * j < N; j += 2) {
/* start at first multiple of j inside the slice */
i = (start + j - 1) / j * j;
/* all multiples below j * j have been cleared already */
if (i < j * j)
i = j * j;
/* only handle odd multiples */
if ((i & 1) == 0)
i += j;
for (; i < stop; i += j + j) {
prime_arr[i] = 0;
}
}
return NULL;
}
int main() {
pthread_t tid[MAX_THREADS] = { 0 };
int i;
for (i = 0; i < MAX_THREADS; i++) {
printf("Creating thread %d\n", i);
pthread_create(&tid[i], NULL, sieveprimes, (void *)(intptr_t)i);
}
for (i = 0; i < MAX_THREADS; i++) {
pthread_join(tid[i], NULL);
}
int count = 0;
for (i = 0; i < N; i++) {
count += prime_arr[i];
//if (prime_arr[i] == 1)
// printf("%d\n", i);
}
printf("%d\n", count);
return 0;
}
Can't increase rows in 2d array, but columns is ok.
#include <stdio.h>
#include <stdlib.h>
it is working:
void increasecolumn(int ** mas, int* n, int m){
for (int i = 0; i < m; i++){
int* tmp = realloc(mas[i], sizeof (*mas[i]) * ((*n) + 1));
if (tmp){
mas[i] = tmp;
}
}
(*n) = (*n) + 1;
}
but increasing rows failed
void increaserow(int ** mas, int n, int* m){
int ** tmp = realloc(mas, sizeof(*mas) * ((*m) + 1));
if (tmp){
mas = tmp;
for (int i = 0; i < 1; i++){
mas[(*m) + i] = malloc(sizeof(*mas[(*m) + i]) * n);
}
}
(*m) = (*m) + 1;
}
int main(int argc, char * argv[]) {
int n = 3; // columns
int m = 2; // rows
int** mas = malloc(m*sizeof(*mas));
for(int i = 0; i < m; i++){
mas[i] = malloc(n*sizeof(*(mas[i])));
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mas[i][j] = 0;
printf("%d ", mas[i][j]);
}
printf("\n");
}
printf("\n");
increasecolumn(mas, &n, m);
for (int i = 0; i < m; i++){
mas[i][n-1] = 1;
}
increaserow(mas, n, &m); // problem is here
for (int j = 0; j < n; j++){
mas[m-1][j] = 0;
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
printf("%d ", mas[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
I use this answer Resizing 2D Arrays in C like an example, something wrong.
The GNU Project Debugger on Windows:
warning: FTH: (9152): * Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *
0 0 0
0 0 0
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401821 in main (argc=1, argv=0x7f1990) at D:\III Курс! II СЕМЕСТР\МатМодДослОп\stud\Untitled2.c:47
47: mas[m-1][j] = 0;