I'm doing some exercise in preparation for my test and in one of those I have to remove duplicated int values from an array:
int *eliminaDup(int *vect, int dim, int *dim_nodup){
int i = 0, newDim = 0, found = 0, j = 0;
int *tmpArr = malloc(dim * sizeof(int));
for(i = 0; i < dim; i++){
j = 0; found = 0;
while(j < newDim && !found){
if(vect[i] == tmpArr[j])
found = 1;
j++;
}
if(!found){
tmpArr[newDim] = vect[i];
newDim++;
}
}
*dim_nodup = newDim;
return (realloc(tmpArr, newDim * sizeof(int)));
}
And in the main method is called this way:
nodup=eliminaDup(input,dim,&dim_nodup);
printf("Print of the new Array: (%d values)\n", dim_nodup);
for (i=0; i<dim_nodup; i++){
printf("%d\n",nodup[i]);
}
But when I try to execute the code, This happens:
ARRAY GIVEN IN INPUT:
[1;2]
OUTPUT:
1
2
OUTPUT EXPECTED:
1
2
...other output from the code...
and as you can see from the screen, the code should go on and print other stuff.
I made some tries and i saw that the code "lock" exactly after the print, but it never came out from the for.
...Why? I'm banging my head on the keyboard.
EDIT: Complete program
#include <stdio.h>
#include <stdlib.h>
int *leggiInput(int *dim);
int *eliminaDup(int *vect, int dim, int *dim_nodup);
int ugualeASomma(int *vect,int dim);
int *maggioreDeiSuccessivi(int *vect, int dim);
int main()
{
int *input, *nodup, *results;
int dim, dim_nodup, i;
//Legge l'input
input=leggiInput(&dim);
printf("Stampa dei valori in input: (%d valori)\n", dim);
for (i=0; i<dim; i++)
printf("%d\n",input[i]);
//Elimina i duplicati
nodup=eliminaDup(input,dim,&dim_nodup);
printf("Stampa dei valori senza duplicati: (%d valori)\n", dim_nodup);
for (i=0; i<dim_nodup; i++){
printf("%d\n",nodup[i]);
}
//Esegue ugualeASomma
printf("Risultato di ugualeASomma: %d\n", ugualeASomma(nodup,dim_nodup));
//Esegue maggioreDeiSuccessivi
results=maggioreDeiSuccessivi(nodup,dim_nodup);
printf("Risultato maggioreDeiSuccessivi:\n");
for(i=0; i<dim_nodup; i++)
printf("%d\n",results[i]);
return 0;
}
int *leggiInput(int *dim){
int n, i;
scanf("%d", &n);
int *arr = malloc(n * sizeof(int));
for(i = 0; i < n; i++){
scanf("%d", &arr[i]);
}
*dim = n;
return arr;
}
int *eliminaDup(int *vect, int dim, int *dim_nodup){
int i = 0, newDim = 0, trovato = 0, j = 0;
int *tmpArr = malloc(dim * sizeof(int));
while(i < dim){
j = 0; trovato = 0;
while(j < newDim && !trovato){
if(vect[i] == tmpArr[j])
trovato = 1;
j++;
}
if(!trovato){
tmpArr[newDim] = vect[i];
newDim++;
}
i++;
}
*dim_nodup = newDim;
return (realloc(tmpArr, newDim * sizeof(int)));
}
int ugualeASomma(int *vect, int dim){
int somma = 0, i = 0, j, trovato = 0;
while(i < dim)
somma += vect[i];
while(i < dim){
if(vect[i] == somma - vect[i])
trovato = 1;
}
return trovato;
}
int *maggioreDeiSuccessivi(int *vect, int dim){
int i = 0, j, trovato;
while(i < dim){
j = i+1; trovato = 0;
while(j < dim && !trovato){
if(vect[i] <= vect[j])
trovato = 1;
else
j++;
}
if(trovato) vect[i] = 0;
else vect[i] = 1;
i++;
}
return vect;
}
EDIT: Solved in comments changing malloc to calloc.
When realloc fails it returns NULL so you should check this and return tmpArr instead:
int* p = realloc(tmpArr, newDim * sizeof(int));
return p != NULL ? p : tmpArr;
it is good practice to initialize all declared variables, even if they will be initialized later. You may later forget about it and assume it is initialized as the function grows.
You have an infinite loop here
int ugualeASomma(int *vect, int dim){
int somma = 0, i = 0, j, trovato = 0;
while(i < dim)
somma += vect[i];
while(i < dim){
if(vect[i] == somma - vect[i])
trovato = 1;
}
return trovato;
}
i is never incremented
I would say Anders Karlsson has a good point. This works fine for me:
int ugualeASomma(int *vect, int dim){
int somma = 0, i = 0, j, trovato = 0;
while(i < dim)
{
somma += vect[i];
if(vect[i] == somma - vect[i])
trovato = 1;
i++;
}
return trovato;
}
Related
When running this code for seeds dataset of size 210*8, I am getting an error after the qsort() line in predict function. It is not executing after the qsort().
I am not sure if qsort is causing this error or why it occurs but any insight would be appreciated.
I get an error when the qsort statement is executed.
My Code:
`include stdio.h
include stdlib.h
include string.h
include math.h
typedef struct point{
int class;
float coords[7], dist;
}point;
int argmax(int arr[], int n){
int marg = -1, mxf = -1, i;
for (i =0; i<= n; i++){
if (arr[i] > mxf){
mxf = arr[i];
marg = i;
}
}
return marg;
}
float get_accuracy(int pred[], int act[], int n){
float cor = 0;
int i;
for (i = 0; i< n; i++){
if (pred[i] == act[i]) cor +=1;
}
return (cor*100.0)/n ;
}
float get_avg(float arr[], int n){
float sum = 0;
int i;
for (i = 0; i<n; i++){
sum += arr[i];
}
return sum/n;
}
point *shuffle(point *dataset, int rows, int features, int groups, int classes)
{
int i,j,k,l,m = 0;
point *shuffled_dataset;
shuffled_dataset = (point *)malloc(sizeof(point)*rows);
for(i=0; i<rows/classes; i++,m++)
{
for(j=0; j<rows/(groups*classes); j++)
{
for(k=0; k<classes; k++,m++)
{
shuffled_dataset[m] = dataset[rows/classes*k + i];
/*for(l=0; l<features; l++)
{
shuffled_dataset[m].coords[l] = dataset[rows/classes*k + i].coords[l];
}*/
}
i++;
}
i--;
}
return shuffled_dataset;
}
float minkowski_dist(float* x, float* y, int len, int p){
int i;
float sum=0;
for(i=0;i < len; i++){
sum += pow(fabs(x[i] - y[i]),p);
}
return pow(sum,1/p);
}
int comparison(const void *a, const void *b) {
point *ia = (point *)a;
point *ib = (point *)b;
return (int)(100.f*ia->dist - 100.f*ib->dist);
}
int predict(point test_point, point train[], int n, int k, int p, int classes, int features){
int i;
printf("Hi\n");
for (i = 0; i < n; i++)
{
train[i].dist = minkowski_dist(test_point.coords, train[i].coords, features, p);
printf("%d.\t", i+1);
print_point(train[i]);
}
qsort (train, n-1, sizeof(train[0]), comparison);
int freq[classes+1];
for (i = 0; i < classes+1; ++i)
freq[i] = 0;
for (i = 0; i < k; i++)
freq[train[i].class]++;
return argmax(freq,classes);
}
float rFoldKNN(point *arr, int num, int r, int k, int p, int classes, int features){
int gsize = num/r;
int i, j, h;
int pred[gsize], act[gsize];
point cval[gsize], train[num - gsize];
float acc[r];
for(i=0; i<r; i++)
{
int cind = 0, tind = 0;
for(j=0; j<gsize; j++)
{
cval[cind++] = arr[gsize*i+j];
for(k=0; k<r; k++)
{
if(k!=i)
{
train[tind++] = arr[gsize*k+j];
}
}
}
for(j=0; j<gsize; j++)
{
printf("%d\t%d\n", tind, cind);
pred[j] = predict(cval[j], train, num-gsize, k, p, classes, features);
act[j] = cval[j].class;
}
acc[i] = get_accuracy(pred, act, gsize);
}
return get_avg(acc,r);
}
int main()
{
FILE *fp;
int r = 10, p = 5, k = 10;
int rows = 210;
int columns = 8;
int classes = 3;
int size = rows * columns; /*Assumed size of the dataset*/
float *data; /*Creating an array of assumed size as 1d(split after every 8 values to get the next row)*/
int count = 0;
int i, j;
float accuracies [k][p], maxac = -1.0;;
int maxk, maxp;
float c;
point *all;
all = (point *)malloc(sizeof(point)*rows);
data = (float*)malloc(sizeof(float*)*size);
if ((fp = fopen("seeds_dataset.txt", "r")) == NULL)
{
printf("Error reading file!");
exit(1);
}
for(i = 0; i < rows; i++){
for (j = 0 ; j < columns; j++){
fscanf(fp,"%f",&c);
if (j == columns-1)
all[i].class = c;
else
all[i].coords[j] = c;
}
}
fclose(fp);
for(i=0; i<rows; i++)
{
printf("%d.\t", i+1);
print_point(all[i]);
}
all = shuffle(all, rows, columns-1, 10, classes);
printf("Hi\n");
for(i=0; i<rows; i++)
{
printf("%d.\t", i+1);
print_point(all[i]);
}
for (i = 1; i <= k; ++i){
for (j = 1; j <= p; ++j){
accuracies[i][j] = rFoldKNN(all, rows, r, i, j, classes, columns-1);
if (accuracies[i][j] > maxac){
maxac = accuracies[i][j];
maxk = i;
maxp = j;
}
}
}
printf("best validation accuracy %f best k %d best p %d ",maxac, maxk, maxp );
return 0;
}
`
free(): invalid next size is the error message you frequently get when you have corrupted the memory arena used by malloc, such as writing beyond the end of an allocated block, destroying in-line accounting information used by the memory allocation functions.
Given the scarcity of actual code in your question (or, after your update, the huge volume of code which you appear not to have slimmed down to more accurately pinpoint the problem), that's about as much detail as I can provide. My suggestion is to examine your code for areas where you don't properly use allocated memory.
int main(){
int word, r=3, i, j;
FILE *fp1 = fopen("key.txt","r");
int **arr = (int **)malloc(sizeof(int *) * r);
for(i = 0;i<r;i++)
arr[i] = (int *)malloc(sizeof(int)*r);
int a = 0, b = 0;
while (!feof(fp1)) {
fscanf(fp1,"%d",&word);
if (b == r){
a++;
b=0;
continue;
}
arr[a][b++] = word;
}
for (i = 0; i < r; i++)
for (j = 0; j < r; j++)
printf("%d \n", arr[i][j]);
fclose(fp1);
}
And this is my key.txt.
0 -1 0
-1 2 -1
0 -1 0
I want to store key.txt in a dynamic 2d array but it did not work. All the time a part of it is missing. Which part is wrong?
You should use fscanf in while, not feof
You should delete continue.
The follow code could work:
#include <stdio.h>
#include <stdlib.h>
int main(){
int word, r=3, i, j;
FILE *fp1 = fopen("key.txt","r");
int **arr = (int **)malloc(sizeof(int *) * r);
for(i = 0;i<r;i++)
arr[i] = (int *)malloc(sizeof(int)*r);
int a = 0, b = 0;
while (fscanf(fp1,"%d",&word) == 1) {
if (b == r) {
a++;
b=0;
}
arr[a][b++] = word;
}
for (i = 0; i < r; i++) {
for (j = 0; j < r; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
fclose(fp1);
return 0;
}
I've made an array that is between [0,1000], and I've printed it. Next step is to arrange the array using switch statements into five different cases 0 to 199, etc. When trying to do so the for loop won't stop. I tried putting a printf after countOne in case 1, no printout occurs either.
Any suggestions
Thanks for your help
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int n;
int arraySize;
int randN;
int rand();
int countOne = 0;
int countTwo = 0;
int countThree = 0;
int countFour = 0;
int countFive = 0;
int countSix = 0;
int *p;
int *p1;
int main()
{
printf("What is the size of the array\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int array[n];
int i;
for (i = 0; i < n; i++) {
randN = rand() % 999;
array[i] = randN;
p = (int*)malloc(i * sizeof(int));
p[i] = array[i];
}
//SORTING THE N-size ARRAY
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
p = (int*)malloc(sizeof(int));
p1 = (int*)malloc(5 * sizeof(int));
p1[0] = countOne;
p1[1] = countTwo;
for (i = 0; i < n; i++) {
switch (i) {
case 1:
for (i = 0; array[i] >= 0 && array[i] <= 199; i++) {
countOne++;
}
case 2:
for (i = 0; array[i] >= 200 && array[i] <= 399; i++) {
countTwo++;
return countTwo;
}
}
}
}
HERE IS MY CODE AS OF CURRENT:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n;
int arraySize;
int randN;
int rand();
int countOne = 0;
int countTwo = 0;
int countThree = 0;
int countFour = 0;
int countFive = 0;
int countSix = 0;
int *p;
int *p1;
printf("What is the size of the array\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int array[n];
int i;
for (i = 0 ; i < n; i++ )
{
randN=rand() % 999;
array[i]=randN;
p=(int*)malloc(i*sizeof(int));
p[i]= array[i];
}
//PRINTING THE N-size ARRAY
for (i = 0; i < n; i++)
{
printf("%i\n", array[i]);
}
//SORTING THE N-size ARRAY
int j;
for (j = 0 ; j < n ; j++)
{
switch(j)
{
case 1:
for(i = 0 ; array[i] >= 0 && array[i] <= 199; i++)
{
countOne++;
return countOne;
}
case 2:
for(i = 0 ; array[i] >= 200 && array[i] <= 399; i++)
{
countTwo++;
return countTwo;
}
}
}
HERE IS THE PRINT OUT:
What is the size of the array
3
823
7
347
There is 0 integers between 0 and 199
There is 0 integers between 200 and 399
The program has many problems.
Here is a simpler version:
#include <stdio.h>
#include <stdlib.h>
int compare_ints(const void *a, const void *b) {
const int *pa = a, *pb = b;
return (*pa > *pb) - (*pa < *pb);
}
int main(void) {
int i, n;
int stats[5] = { 0, 0, 0, 0, 0 };
printf("What is the size of the array?\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int *array = malloc(n * sizeof(int));
int *saved = malloc(n * sizeof(int));
if (array == NULL || saved == NULL) {
printf("cannot allocate arrays\n");
exit(1);
}
for (i = 0; i < n; i++) {
int randN = rand() % 999;
saved[i] = array[i] = randN;
stats[randN / 200] += 1;
}
printf("initial array contents:\n);
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
printf("\n");
//SORTING THE N-size ARRAY
qsort(array, n, sizeof(*array), compare_ints);
printf("sorted array:\n);
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
printf("\n");
for (i = 0; i < 5; i++) {
printf("%d values between %d and %d\n", stats[i], i * 200, (i + 1) * 200 - 1);
}
printf("\n");
// do whatever else you are supposed to with array and saved
//...
free(array);
free(saved);
return 0;
}
I am trying to create C program to read a text file and sort it by ascending order. The example of text file is
2
3; 2, 5, 7
6; 4, 7, 8, 9, 5, 2
with the first line indicated the number of rows, the number after the ";" indicated elements each rows and elements separated by ",".
So my idea is to create a dynamic jagged array with rows as the first number, then point each row to the different array with element. Sort the pointer arrays first then sort elements of each arrays. This is what I have tried so far
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int SortLists();
int main ()
{
int i,j = 0;
char filename[10]; //name of the file
char line[100];
int rows = 3; //I have to initialized this to test my code first
int cols;
int **jaggedArr; //jagged array
jaggerArr = malloc (rows*sizeof(int*)) ;
printf("Enter the file name with .txt : ");
scanf("%s", filename);
FILE *filePtr = fopen(filename, "r");
int num;
if (filePtr != NULL)
{
while (fgets(line, sizeof(line), filePtr) != NULL) //read each line of the text
{
cols = atoi(strtok(line, ";")); //use strtk to break elements
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
jaggedArr[i][j] = atoi(strtok(line, ",")); //parse into the jagged array
}
}
}
fclose(filePtr);
}
}
int SortLists(int list[], int size) //sort method
{
int i,j,temp;
for (i = 0; i < size; ++i)
{
for (j = i + 1; j < size; ++j)
{
if (list[i] > list[j])
{
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
As a beginner in C, I am not familiar with the idea of pointer, which a lot different with C#.
Sorry for my bad English as its not my first language. Thank you so much for helping me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S_(x) #x
#define S(x) S_(x)
void SortLists(int list[], int size);
int main(void){
char filename[FILENAME_MAX+1];
char line[100];
int rows, cols;
printf("Enter the file name with .txt : ");
scanf("%" S(FILENAME_MAX) "[^\n]%*c", filename);
FILE *filePtr = fopen(filename, "r");
if(!filePtr)
return EXIT_FAILURE;
fscanf(filePtr, "%d ", &rows);
int **jaggedArr;
jaggedArr = malloc (rows * sizeof(int*));
int *sizeArr = malloc(rows * sizeof(int));
int r = 0, c;
while (fgets(line, sizeof(line), filePtr) != NULL){
sizeArr[r] = cols = atoi(strtok(line, ";"));
jaggedArr[r] = malloc(cols * sizeof(int));
for (c = 0; c < cols; ++c){
jaggedArr[r][c] = atoi(strtok(NULL, ","));
}
SortLists(jaggedArr[r++], cols);
}
fclose(filePtr);
//check print and deallocation
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
free(jaggedArr[r]);
}
free(jaggedArr);
free(sizeArr);
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
for extra question.
#include <stdio.h>
void SortLists(int list[], int size);
void SortRows(int *jaggedArr[], int size, int *rowSize);
int main(void){
int row1[] = {4,7,8,9,5,2};
int row2[] = {2,5,7};
int *jaggedArr[] = { row1, row2};
int rows = 2;
int sizeArr[] = {6,3};
int i, r, c;
for(i=0;i<rows;++i)
SortLists(jaggedArr[i], sizeArr[i]);
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
printf("\n");
SortRows(jaggedArr, rows, sizeArr);
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
void SortRows(int *jaggedArr[], int size, int *rowSize){
int i,j,temp,*tempp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (rowSize[i] > rowSize[j]){
//swap in pairs
temp = rowSize[i];
rowSize[i] = rowSize[j];
rowSize[j] = temp;
tempp = jaggedArr[i];
jaggedArr[i] = jaggedArr[j];
jaggedArr[j] = tempp;
}
}
}
}
#include <stdio.h>
void SortLists(int list[], int size);
void SortRows(int *jaggedArr[], int size);
int main(void){
int row1[] = {6, 4,7,8,9,5,2};//The first element represents the number of elements.
int row2[] = {3, 2,5,7};
int *jaggedArr[] = { row1, row2};
int rows = 2;
//int sizeArr[] = {6,3};//Not required
int i, r, c;
for(i=0;i<rows;++i)
SortLists(jaggedArr[i]+1, jaggedArr[i][0]);
SortRows(jaggedArr, rows);
for(r = 0;r < rows; ++r){
for(c = 1; c <= jaggedArr[r][0]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
void SortRows(int *jaggedArr[], int size){
int i,j,*tempp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (jaggedArr[i][0] > jaggedArr[j][0]){
tempp = jaggedArr[i];
jaggedArr[i] = jaggedArr[j];
jaggedArr[j] = tempp;
}
}
}
}
I have this parallel Gaussian elimination code. A segmentation error happens upon calling either MPI_Gather function calls. I know such error may rise if memory is not allocated properly for either buffers. But I cannot see any wrong with the memory management code.
Can someone help?
Thanks.
Notes:
The program reads from a .txt file in the same directory called input.txt.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"
/*void print2dAddresses(double** array2d, int rows, int cols)
{
int i;
for(i = 0; i < rows; i++)
{
int j;
for(j = 0; j < cols; j++)
{
printf("%d ", &(array2d[i][j]));
}
printf("\n");
}
printf("------------------------------------");
}*/
double** newMatrix(int rows, int cols)
{
double *data = (double*) malloc(rows * cols * sizeof(double));
double **array= (double **)malloc(rows * sizeof(double*));
int i;
for (i=0; i<rows; i++)
array[i] = &(data[cols*i]);
return array;
}
void freeMatrix(double** mat)
{
free(mat[0]);
free(mat);
}
double** new2dArray(int nrows, int ncols)
{
int i;
double** array2d;
array2d = (double**) malloc(nrows * sizeof(double*));
for(i = 0; i < nrows; i++)
{
array2d[i] = (double*) malloc(ncols * sizeof(double));
}
return array2d;
}
double* new1dArray(int size)
{
return (double*) malloc(size * sizeof(double));
}
void free2dArray(double** array2d, int nrows)
{
int i;
for(i = 0; i < nrows; i++)
{
free(array2d[i]);
}
free(array2d);
}
void print2dArray(double** array2d, int nrows, int ncols)
{
int i, j;
for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncols; j++)
{
printf("%lf ", array2d[i][j]);
}
printf("\n");
}
printf("----------------------\n");
}
void print1dArray(double* array, int size)
{
int i;
for(i = 0; i < size; i++)
{
printf("%lf\n", array[i]);
}
printf("----------------------\n");
}
void read2dArray(FILE* fp, double** array2d, int nrows, int ncols)
{
int i, j;
for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncols; j++)
{
fscanf(fp, "%lf", &(array2d[i][j]));
}
}
}
void read1dArray(FILE* fp, double* array, int size)
{
int i;
for(i = 0; i < size; i++)
{
fscanf(fp, "%lf", &(array[i]));
}
}
void readSymbols(char* symbols, int size, FILE* fp)
{
int i;
for(i = 0; i < size; i++)
{
char c = '\n';
while(c == '\n' | c == ' ' | c == '\t' | c == '\r')
fscanf(fp, "%c", &c);
symbols[i] = c;
}
}
void printSolution(char* symbols, double* x, int size)
{
int i;
for(i = 0; i < size; i++)
{
printf("%c = %lf\n", symbols[i], x[i]);
}
}
double* copy_1d_array(double* original, int size)
{
double* copy_version;
int i;
copy_version = (double*) malloc(size * sizeof(double));
for(i = 0; i < size; i++)
{
copy_version[i] = original[i];
}
return copy_version;
}
int main(int argc, char** argv)
{
int p, rank, i, j, k, l, msize, rowsPerProcess, remainder, startingRow, dest, rowCounter, remainingRows, neededProcesses;
double **A, *b, *x, **smallA, *currentRow, *smallB, currentB, **receivedA, *receivedB;
char *symbols;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == 0)
{
FILE* fp;
fp = fopen("input.txt", "r");
fscanf(fp, "%d", &msize);
A = newMatrix(msize, msize);
b = new1dArray(msize);
x = new1dArray(msize);
symbols = (char*) malloc(msize * sizeof(char));
read2dArray(fp, A, msize, msize);
read1dArray(fp, b, msize);
readSymbols(symbols, msize, fp);
fclose(fp);
/*print2dArray(A, msize, msize);
print1dArray(b, msize);*/
}
MPI_Bcast(&msize, 1, MPI_INT, 0, MPI_COMM_WORLD);
for(i = 0; i < (msize - 1); i++)
{
int maxIndex;
double maxCoef, tmp, r;
/*finding max row*/
if(rank == 0)
{
maxIndex = i;
maxCoef = fabs(A[i][i]);
for(j = i + 1; j < msize; j++)
{
if(fabs(A[j][i]) > maxCoef)
{
maxCoef = A[j][i];
maxIndex = j;
}
}
/*swapping the current row with the max row*/
for(j = 0; j < msize; j++)
{
tmp = A[i][j];
A[i][j] = A[maxIndex][j];
A[maxIndex][j] = tmp;
}
tmp = b[i];
b[i] = b[maxIndex];
b[maxIndex] = tmp;
/*elimination*/
/*for(j = i + 1; j < msize; j++)
{
double r = A[j][i] / A[i][i];
subtracting r * row i from row j
for(k = i; k < msize; k++)
{
A[j][k] -= r * A[i][k];
}
b[j] -= r * b[i];
}*/
/*parallel elimination*/
startingRow = i + 1;
neededProcesses = p;
remainingRows = msize - startingRow;
if(remainingRows < neededProcesses)
{
neededProcesses = remainingRows;
}
rowsPerProcess = remainingRows / neededProcesses;
remainder = remainingRows % neededProcesses;
}
MPI_Bcast(&startingRow, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&rowsPerProcess, 1, MPI_INT, 0, MPI_COMM_WORLD);
if(rank == 0)
{
currentRow = copy_1d_array(A[startingRow-1], msize);
currentB = b[startingRow-1];
}
else
{
currentRow = new1dArray(msize);
}
MPI_Bcast(currentRow, msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(¤tB, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
if(rank == 0)
{
receivedA = newMatrix(remainingRows, msize);
receivedB = new1dArray(remainingRows);
}
smallA = newMatrix(rowsPerProcess, msize);
smallB = new1dArray(rowsPerProcess);
MPI_Scatter(&(A[startingRow][0]), rowsPerProcess*msize, MPI_DOUBLE, &(smallA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Scatter(&(b[startingRow]), rowsPerProcess, MPI_DOUBLE, &(smallB[0]), rowsPerProcess, MPI_DOUBLE, 0, MPI_COMM_WORLD);
for(j = 0; j < rowsPerProcess; j++)
{
r = smallA[j][startingRow-1] / currentRow[startingRow-1];
for(k = 0; k < msize; k++)
{
smallA[j][k] -= r * currentRow[k];
}
smallB[j] -= r * currentB;
}
MPI_Gather(&(smallA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, &(receivedA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Gather(&(smallB[0]), rowsPerProcess, MPI_DOUBLE, &(receivedB[0]), rowsPerProcess, MPI_DOUBLE, 0, MPI_COMM_WORLD);
freeMatrix(smallA);
free(smallB);
if(rank == 0)
{
for(j = 0; j < remainingRows; j++)
{
for(k = 0; k < msize; k++)
{
A[j+startingRow][k] = receivedA[j][k];
}
b[j+startingRow] = receivedB[j];
}
free(currentRow);
freeMatrix(receivedA);
free(receivedB);
}
if(rank == 0)
{
if(remainder > 0)
{
for(j = (msize - remainder); j < msize; j++)
{
r = A[j][i] / A[i][i];
for(k = 0; k < msize; k++)
{
A[j][k] -= r * A[i][k];
}
b[j] -= r * b[i];
}
}
}
}
if(rank == 0)
{
/*backward substitution*/
for(i = msize - 1; i >= 0; i--)
{
x[i] = b[i];
for(j = msize - 1; j > i; j--)
{
x[i] -= A[i][j] * x[j];
}
x[i] /= A[i][i];
}
printf("solution = \n");
//print1dArray(x, msize);
printSolution(symbols, x, msize);
freeMatrix(A);
free(b);
free(x);
free(symbols);
}
MPI_Finalize();
return 0;
}
Input File:
3
1 1 1
1 1 3
2 1 4
4
9
12
x
y
z
It might be this: &(receivedA[0][0]) on processes where rank != 0. You're indexing an array that hasn't been allocated. You might have to create another pointer, like this:
if(rank == 0)
{
receivedA = newMatrix(remainingRows, msize);
recievedAHead = &(receivedA[0][0]);
receivedB = new1dArray(remainingRows);
}
else {
recievedAHead = NULL;
}
and use recievedAHead in the MPI_Gather call.