*pointer was nullptr* error in C programming - c

I have a serious problame.
at the line **c = (int*)malloc(size1 * sizeof(int*));
the compiler gives me this error which I don't really know what it says.
Unhandled exception thrown: read access violation.
c was nullptr. occurred
I don't know what I'm doing wrong..
I initialize every pointer like this.
void BuildMatrix(int ***, int, int);
void FreeMatrix(int ***, int);
void PrintMatrix(int **, int, int);
int **MultiplyMatrixes(int **, int**, int, int, int);
int main() {
int **matrix1 = NULL, **matrix2 = NULL, **matrix3 = NULL;
int * newCol = NULL;
int size1, size2, size3, newRow;
printf("-How many rows in the first matrix?: ");
scanf("%d", &size1);
printf("-How many columns in the first matrix and second?[size2, size3]: ");
scanf("%d %d", &size2, &size3); /*size2 = rows of matrix2.*/
/*Build both matrices*/
printf("-First matrix input.\n");
BuildMatrix(&matrix1, size1, size2);
PrintMatrix(matrix1, size1, size2);
printf("-Second matrix input.\n");
BuildMatrix(&matrix2, size2, size3);
PrintMatrix(matrix2, size2, size3);
/*Combine the 2 matrices to a new matrix*/
matrix3 = MultiplyMatrixes(matrix1, matrix2, size1, size2, size3);
FreeMatrix(&matrix2, size2); //Free the second matrix
printf("\n-Multiplied matrix: \n");
PrintMatrix(matrix3, size1, size3);
FreeMatrix(&matrix3, size1);
FreeMatrix(&matrix1, size1);
}
void BuildMatrix(int *** pMat, int row, int col) {
int i, j;
(*pMat) = (int **)malloc(row * sizeof(int*));
if (*pMat == NULL) {
free(pMat);
printf("*Not enough RAM.\nTerminating.\n");
exit(1);
}
for (i = 0; i < row; i++) {
(*pMat)[i] = (int *)malloc(col * sizeof(int*));
if ((*pMat)[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(pMat, row);
exit(1);
}
for (j = 0; j < col; j++) {
printf("-Enter %d element in %d row: ", j + 1, i + 1);
scanf("%d", &(*pMat)[i][j]);
}
printf("\n");
}
//FreeMatrix(pMat, row);
}
void PrintMatrix(int ** pMat, int row, int col) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
printf("%d ", pMat[i][j]);
}
printf("\n");
}
}
int** MultiplyMatrixes(int ** a, int ** b, int size1, int size2, int size3) {
int i, j, k, **c = NULL;
**c = (int*)malloc(size1 * sizeof(int*));
if (c == NULL) {
free(*c);
printf("*Not enough RAM.\nTerminating.\n");
exit(1);
}
for (i = 0; i < size1; i++) {
for (j = 0; j < size3; j++) {
c[i] = (int *)malloc(size3 * sizeof(int));
if (c[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(&c, size1);
exit(1);
}
for (k = 0; k < size2; k++) {
c[i][j] += (a[i][k] * b[k][j]);
}
}
}
return c;
}

(*pMat)[i] = (int *)malloc(col * sizeof(int*));
will be
(*pMat)[i] = malloc(col * sizeof(int));
You have allocated space for col number of int* where you are reading int-s.
Also
**c = (int*)malloc(size1 * sizeof(int*));
will be
c = malloc(size1 * sizeof(int*));
Otherwise you were trying to dereference NULL value which triggered the error you got.
Also the loop will be
for (i = 0; i < size1; i++) {
c[i] = malloc(size3 * sizeof(int));
if (c[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(&c, size1);
exit(1);
}
for (j = 0; j < size3; j++) {
c[i][j]=0;
for (k = 0; k < size2; k++) {
c[i][j] += (a[i][k] * b[k][j]);
}
}
}
Don't cast the return value of malloc.

Related

I want to show elements of a matrix that appear only once

I got this but it I can't seem to make it work, tried everything I could think of.
#include <stdio.h>
#include <stdlib.h>
void alocare_vector(int *v, int nr, int elem)
{
int *v1;
if ((v1 = realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, *v = NULL, i, j, k, l, ok = 0, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (k = 0; k < n; k++)
{
for (l = 0; l < n; l++)
{
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (a[k][l] == a[i][j] && (k != i && l != j))
ok = 1;
if (ok == 0)
{
nr++;
alocare_vector(v, nr, a[k][l]);
}
ok = 0;
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
Basically, I need to create a matrix, ans print the elements that appear only once using an array with dynamic memory allocation.
one simple fix is to declare the "int * v" as a global variable and modify the function as alocare_vector(int nr, int elem)
now using a hash table you can store the numbers in the array, below is the your implementation just a bit modified.
#include <stdio.h>
#include <stdlib.h>
int hash[1000]={0};
int * v=NULL;
void alocare_vector(int nr, int elem)
{
int *v1;
if ((v1 = (int*)realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, i, j, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
++hash[a[i][j]];
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if(hash[a[i][j]]==1)
{
nr++;
alocare_vector(nr, a[i][j]);
}
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
When calling a your funtion you pass a copy of the pointer. Therfore any modifications to this local copy of the pointer will not affect the copy in main. Therfore you need a refrence or pointer to the pointer in main.
void alocare_vector(int **v, int nr, int elem)
{
...
*v = v1;
}
Here you have brut force example how to generate array of distinct elements of the 2D array:
typedef struct
{
size_t length;
int data[];
}data_t;
data_t *add_element(data_t *arr, int element)
{
size_t newsize = arr ? arr -> length : 0;
arr = realloc(arr, newsize * sizeof(arr -> data[0]) + sizeof(*arr));
if(arr)
{
arr -> length = newsize;
arr -> data[newsize - 1] = element;
}
return arr;
}
int isPresent(size_t rows, size_t cols, size_t vrow, size_t vcol, int (*array)[cols])
{
int val = array[vrow][vcol];
for(size_t row = 0; row < rows; row++)
for(size_t col = 0; col < cols; col++)
{
if(vcol == col && vrow == row) continue;
if(array[row][col] == val)
{
return 1;
}
}
return 0;
}
data_t *distinctElements(size_t rows, size_t cols, int (*array)[cols])
{
data_t *dist = NULL;
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
if(!isPresent(rows, cols, row, col, array))
{
data_t *tmp = add_element(dist, array[row][col]);
if(tmp) dist = tmp;
else { /* error handling */}
}
}
}
return dist;
}

Difference between malloc and calloc in this case?

This is a code for multiplying two square matrices in C.
What is the difference between using malloc and calloc in void multiply() function?
When using malloc, I am getting garbage values, but calloc is providing the right answer.
Only the first row is outputting garbage values so is it an issue with the way malloc allocates space in the heap as compared to calloc?
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(int *, int, int);
void multiply(int *, int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
scanf("%d", &n);
int *arr1;
int *arr2;
arr1 = getArray(n);
display(arr1, n, n);
printf("\n now give input for next array");
arr2 = getArray(n);
display(arr2, n, n);
printf("\n\n\n");
multiply(arr1, arr2, n);
return 0;
}
int *getArray(int n) {
int *arr = (int *)malloc(n * n * sizeof(int));
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", (arr + i * n + j));
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(" %d ", *(arr + i * n + j));
}
printf("\n");
}*/
return arr;
}
void display(int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %d ", *(arr + i * row + j));
}
printf("\n");
}
}
void multiply(int *arr1, int *arr2, int n) {
int *arr = (int *)calloc(n * n, sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
printf("product of above matrices = \n\n");
display(arr, n, n);
}
The only functional difference between allocating memory with malloc() and with calloc() for the same size, assuming the size computation is accurate, is the latter initializes the block to all bits 0, whereas the former does not.
All bits 0 means all int values in the array are initialized to 0.
The inner loop in the multiply function only increments the element at row i and column j, therefore the function relies on implicit initialization of the array elements to 0. calloc() does that, but not malloc() so you definitely need to use calloc().
Also note these remarks:
in display the computation for the offset of the matrix element at row i column j should be printf(" %5d ", *(arr + i * col + j));
multiply should return arr and display() should be called in the main function.
you should check for scanf(), malloc() and calloc()` failure
you should free allocated memory
pointer arguments to objects that are not modified by the function should be const qualified so the function can be called with a pointer to a const object.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(const int *, int, int);
int *multiply(const int *, const int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
if (scanf("%d", &n) != 1)
return 1;
printf("\n now give input for the first array");
int *arr1 = getArray(n);
if (!arr1)
return 1;
display(arr1, n, n);
printf("\n now give input for the second array");
int *arr2 = getArray(n);
if (!arr2)
return 1;
display(arr2, n, n);
printf("\n\n\n");
int *arr = multiply(arr1, arr2, n);
if (!arr)
return 1;
printf("product of above matrices = \n\n");
display(arr, n, n);
free(arr1);
free(arr2);
free(arr);
return 0;
}
int *getArray(int n) {
int *arr = malloc(sizeof(int) * n * n);
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", (arr + i * n + j)) != 1) {
free(arr);
return NULL;
}
}
}
return arr;
}
void display(const int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %5d ", *(arr + i * col + j));
}
printf("\n");
}
}
int *multiply(const int *arr1, const int *arr2, int n) {
int *arr = calloc((size_t)n * n, sizeof(int));
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
return arr;
}

Heap Corruption on resize array by realloc() function in C

I have a problem with increasing C[] array from 6 to 10 I've faced with heap corruption problem by realloc(). I have a following code of Big M metod:
#include <stdio.h>
#include <stdlib.h>
int * mnInit(FILE * );
double * * ReadA(FILE * , int, int);
double * ReadVector(FILE * , int);
int * condtxt(FILE *, int );
void Artif_counter(int* , int *, int);
void reallocationA(double**, int* , int , int);
void increaseA(int*, double**, int, int, int);
void increaseC(double *, int);
int main(int argc, char * argv[]) {
FILE * file1 = fopen("C.txt", "r");
FILE * file4 = fopen("A.txt", "r");
FILE * file5 = fopen("Agetmn.txt", "r");
FILE * file6 = fopen("cond.txt", "r");
int * ptr_mn;
ptr_mn = mnInit(file5);
int n = * (ptr_mn);
int m = * (ptr_mn + 1);
double * * A;
A = ReadA(file4, n, m);
double * C;
C = ReadVector(file1, n);
int * cond;
cond = condtxt(file6, m);
for(int i = 0; i < m; i++){
}
//--------------------------------------------------
int BAcounter = 0;
Artif_counter(cond, &BAcounter, m);
printf("\n Basys and Artifical variable = %d", BAcounter);
reallocationA(A, &n, m, BAcounter);
increaseA(cond, A, n, m, BAcounter);
this function dont't working
increaseC(C, n);
When I trying to print arrays: the A[][] was printed right while C[] array was printed by unknown numbers and after the program Mmetod.exe was closed with problem: A heap has been corrupted (parameters: 0x00007FFCA0C1F6B0).
// count of basys and artif
//------------------------------------------------After Adding a new columns:
printf("\n A[][] ARRAY:\n");
for (int i = 0; i < m; i++) {
printf("%d ", i);
for (int j = 0; j < n; j++) {
printf(" %.3f ", A[i][j]);
}
printf("\n");
}
printf("\n\tVECTOR C[]:\n");
for (int i = 0; i < n; i++) {
printf("%lf ", C[i]);
}
fclose(file1);
fclose(file4);
fclose(file5);
fclose(file6);
free(C);
for (int i = 0; i < m; i++) {
free(A[i]);
}
free(A);
printf("\n\n");
system("pause");
return 0;
}
int * mnInit(FILE * file) {
int c;
int digit = 0;
int column = 0;
int * mnArray = malloc(2 * sizeof( * mnArray));
if (file == NULL) perror("Warning!");
else {
while (!feof(file)) {
c = fgetc(file);
if (c == ';') {
column++;
}
if (c == ' ') {
digit++;
}
}
}
* (mnArray) = (digit / column) + 1; * (mnArray + 1) = column;
return mnArray;
}
double * * ReadA(FILE * file, int n, int m) {
double * * A = malloc(m * sizeof( * A));
for (int i = 0; i < m; i++) {
A[i] = malloc(n * sizeof( * A[i]));
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//fscanf(file ,"%lf ", &(*(*(A + i) + j)));
fscanf(file, "%lf ", & A[i][j]);
}
fscanf(file, "\n");
}
return A;
}
double * ReadVector(FILE * file, int m) { // ++++
double * Vector = malloc(m * sizeof( * Vector));
for (int i = 0; i < m; i++) {
fscanf(file, "%lf ", Vector + i);
}
return Vector;
}
int* condtxt(FILE * file, int m){
int * condA = malloc(m * sizeof(*condA));
for(int i = 0; i < m; i++){
fscanf(file, "%d", &condA[i]);
}
return condA;
}
void Artif_counter(int * cond, int *k, int m){
for(int i = 0; i < m; i++){
if(cond[i] == -1){
(*k)++;
}
if(cond[i] == 0){
(*k)++;
}
if(cond[i] == 1){
*k = (*k) + 2;
}
}
}
void reallocationA(double** A, int* n, int m, int k){
double * tmp = NULL;
for(int i = 0; i < m; i++){
tmp = realloc(A[i], ((*n) + k)*sizeof(*A[i]));
if(tmp){
A[i] = tmp;
tmp = NULL;
} else{
printf("Error! Memory isn't reallocated'");
tmp = NULL;
}
}
(*n) = (*n) + k;
}
void increaseA(int* cond, double** A, int n, int m, int k){
int presentcol = n-k;
for(int i = 0; i < m; i++){
if(cond[i] == -1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 0){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
A[j][presentcol + 1] = -1;
} else {
A[j][presentcol] = 0;
A[j][presentcol + 1] = 0;
}
}
presentcol = presentcol + 2;
}
}
}
When I wanted to increase an array in a simple code by this function it've done and I don't understand why(
A GNU debugger rewiev: 0 warning: Critical error detected c0000374
void increaseC(double * C, int n){
double * tmp;
tmp = realloc(C, (n)*sizeof(*C)); // found out that realloc function caused an error
if(!tmp){
printf("Error");
} else{
C = tmp;
}
tmp = NULL;
}

Should I should use pointers in this C code? Where? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Here is my code. It is a C program using Gauss Elimination Method and Partial Pivoting to solve systems of linear algebraic equations. Would you tell me when it is better to use pointers?
typedef double **Matrix;
typedef double *Row;
typedef double *Col;
typedef double Elem;
Matrix allocate_matrix(int n);
Col allocate_col(int n);
Row allocate_row(int n);
void free_matrix(Matrix M, int n);
void pivot_partial(Matrix A, Col S,Col B, int n);
void forward_elimination(Matrix A,Col B,int n);
Col back_substitution(Matrix A, Col B, int n);
Col scale_factor(Matrix A,int n);
void gauss(Matrix A, Col B, int n);
void swap_rows(Row *r1, Row*r2);
void print_matrix(Matrix M, int n, char * name);
void print_col(Col C, int n, char *name);
void print_row(Row R, int n, char *name);
int main(int argc, char *argv[])
{
FILE *ifp;
int n,i,j;
Matrix A;
Col B;
if(argc < 2)
{
printf("\nInput filename not passed \n");
exit(1);
}
ifp = fopen(argv[1],"r");
if(ifp == NULL)
{
printf("\nCould not open file %s\n",argv[1]);
exit(1);
}
fscanf(ifp,"%i",&n);
printf("A * X = B\n");
printf("\nDimension(A) = %i\n",n);
A = allocate_matrix(n);
for( i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
fscanf(ifp,"%lf", &A[i][j]);
B = allocate_col(n);
for(j = 1; j <= n; ++j)
fscanf(ifp,"%lf",&B[j]);
fclose(ifp);
print_matrix(A,n,"A");
print_col(B,n,"B");
gauss(A,B,n);
free_matrix(A,n);
free(B + 1);
getchar();
return 0;
}
void print_matrix(Matrix M, int n, char * name)
{
int i,j;
printf("\n[%s] = ",name);
printf("\n\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; ++j)
printf("%6lG ",M[i][j]);
printf("\n");
}
}
void print_col(Col C, int n, char * name)
{
int j;
printf("\n[%s] = ",name);
printf("\n\n");
for(j = 1; j <= n; ++j)
printf("%6lg\n",C[j]);
}
void print_row(Row R, int n, char * name)
{
int i;
printf("\n[%s] = ",name);
for(i = 1; i <= n; ++i)
printf("%6lg ",R[i]);
printf("\n");
}
Matrix allocate_matrix(int n)
{
Matrix A;
int i,j;
A = malloc(n * sizeof(Row));
if(!A)
{
printf("\nError : Could not allocate
memory for matrix\n");
exit(1);
}
--A;
for(i = 1; i <= n; ++i)
{
A[i] = malloc(n * sizeof(Elem));
if(!A[i])
{
printf("\nError : Could not allocate
memory for matrix\n");
exit(1);
}
--A[i];
}
return A;
}
void free_matrix(Matrix M, int n)
{
int i;
for(i = 1; i <= n; ++i)
free(M[i] + 1);
free(M + 1);
}
Col allocate_col(int n)
{
Col B;
B = malloc(n * sizeof(Elem));
if(!B)
{
printf("\nError : could not allocate
memory\n");
exit(1);
}
--B;
return B;
}
Row allocate_row(int n)
{
Row B;
B = malloc(n * sizeof(Elem));
if(!B)
{
printf("\nError : could not allocate
memory\n");
exit(1);
}
--B;
return B;
}
Col scale_factor(Matrix A, int n)
{
int i,j;
Col S ;
S = allocate_col(n);
for(i = 1; i <= n; ++i)
{
S[i] = A[i][1];
for(j = 2; j <= n; ++j)
{
if(S[i] < fabs(A[i][j]))
S[i] = fabs(A[i][j]);
}
}
return S;
}
void pivot_partial(Matrix A, Col S,Col B, int n)
{
int i,j;
Elem temp;
for(j = 1; j <= n; ++j)
{
for(i = j + 1; i <= n; ++i)
{
if(S[i] == 0)
{
if(B[i] == 0)
printf("\nSystem doesnt
have a unique solution");
else
printf("\nSystem is
inconsistent");
exit(1);
}
if(fabs(A[i][j]/S[i])>fabs(A[j][j]/S[j]))
{
swap_rows(&A[i],&A[j]);
temp = B[i];
B[i] = B[j];
B[j] = temp;
}
}
if(A[j][j] == 0)
{
printf("\nSingular System Detected\n");
exit(1);
}
}
}
void swap_rows(Row *r1, Row*r2)
{
Row temp;
temp = *r1;
*r1 = *r2;
*r2 = temp;
}
void forward_elimination(Matrix A,Col B,int n)
{
int i,j,k;
double m;
for(k = 1; k <= n-1; ++k)
{
for(i = k + 1; i <= n; ++i)
{
m = A[i][k] / A[k][k];
for(j = k + 1; j <= n; ++j)
{
A[i][j] -= m * A[k][j];
if(i == j && A[i][j] == 0)
{
printf("\nSingular
system detected");
exit(1);
}
}
B[i] -= m * B[k];
}
}
}
Col back_substitution(Matrix A, Col B, int n)
{
int i,j;
Elem sum;
Col X = allocate_col(n);
X[n] = B[n]/A[n][n];
for(i = n - 1; i >= 1; --i)
{
sum = 0;
for(j = i + 1; j <= n; ++j)
sum += A[i][j] * X[j];
X[i] = (B[i] - sum) / A[i][i];
}
return X;
}
void gauss(Matrix A, Col B, int n)
{
int i,j;
Col S, X;
S = scale_factor(A,n);
pivot_partial(A,S,B,n);
forward_elimination(A,B,n);
X = back_substitution(A,B,n);
print_col(X,n,"X");
free(S + 1);
free(X + 1);
}
If you don't know in advance the size of the array (Matrix), use pointers.
Arrays once declared with a particular size cannot grow or shrink.
But, pointers on the other hand, can be allocated memory (using malloc()), deallocated memory (using free()) and reallocated memory (using realloc()).
In your code, these lines
A = allocate_matrix(n);
for( i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
fscanf(ifp,"%lf", &A[i][j]);
dynamically allocate a matrix A, after reading the size from file. This isn't possible in case of arrays.

MPI_Gather segmentation fault

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(&currentB, 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.

Resources