I'm writing a program to read numbers from a .txt file to then put into a 2-dimensional matrix that I can use to do matrix multiplication with but at this point I'm having alot of trouble getting the portion of my code that scans the file to work properly. I have two randomly generated matrixes that I'm using and for the smaller one it will read the first 400 values but then the rest of the array will be zeros. For the larger one, which is 4000x4000, it will just throw a segmentation fault without even going into the main. Any ideas at what would be causing this? I change ARRAY_SIZE to whatever the array length and Width are.
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 4000
int main(int argc, char *argv[]) {
// Form to read: ./programname #ofthreads inputfilename1 inputefilename2 outputfilename
if(argc != 5) {
printf("Error! usage: ./programname #ofthreads inputfilename1 inputfilename2 outputfilename");
return (EXIT_FAILURE);
}
// get number of threads
int numThreads = atoi(argv[1]);
// make file pointers
FILE *fp1;
FILE *fp2;
// assign pointer to file name
fp1 = fopen(argv[2], "r");
fp2 = fopen(argv[3], "r");
// Error Handling if file doesn't exist
if (fp1 == NULL) {
printf("Error: File 1 does not exist. ");
return (EXIT_FAILURE);
}
if (fp2 == NULL) {
printf("Error: File 2 does not exist. ");
return (EXIT_FAILURE);
}
// initialize arrays
int array1[ARRAY_SIZE][ARRAY_SIZE] = {0};
int array2[ARRAY_SIZE][ARRAY_SIZE] = {0};
// initialize dimension ints
int size1[2];
int size2[2];
// Get Dimensions
fscanf(fp1,"%d ",&size1[0]);
fscanf(fp1,"%d \n", &size1[1]);
fscanf(fp2,"%d ",&size2[0]);
fscanf(fp2,"%d \n", &size2[1]);
int length1 = size1[0];
int width1 = size1[1];
int length2 = size2[0];
int width2 = size2[1];
for(int n = 0; n < length1; n ){
for(int m = 0; m < width1; m ){
fscanf(fp1, "%d ", &array1[m][n]);
}
}
for(int n = 0; n < length2; n ){
for(int m = 0; m < width2; m ){
fscanf(fp1, "%d ", &array2[m][n]);
}
}
// Process file here
// Close file
fclose(fp1);
fclose(fp2);
for(int n = 0; n < width1; n ){
for(int m = 0; m < length1; m ){
// printf("%d ", array1[m][n]);
}
printf("\n");
}
printf("Number of threads = %d\n", numThreads);
printf("Size1 = %d x %d\n", size1[0],size1[1]);
printf("Size2 = %d x %d\n", size2[0],size2[1]);
return 0;
}
CodePudding user response:
Process stack size is limited (few MiBs). It varies between systems based on OS implementation. If you need anything over that, better get it from heap (Memory management calls).
int rows = 4000;
int cols = 4000;
int **array = (int**) malloc (rows * sizeof(int*));
if (!array) {
perror("malloc1");
exit(1);
}
for (ri = 0; ri < rows; ri) {
array[ri] = (int*) malloc (cols * sizeof(int));
if (!array[ri]) {
perror("malloc2");
exit(2);
}
}
Remember to free the allocated memory in reverse order. First the columns' (loop) then the rows'.
Edit:
Assuming you allocated both array1
& array2
using malloc()
calls.
Reading array2
contents
fscanf(fp1, "%d ", &array2[m][n]);
shouldn't that be fp2
?
CodePudding user response:
2 x 4000 x 4000 int
s will most probably take up more stack space than you have available. Allocate the memory dynamically using calloc
instead (declared in stdlib.h
):
// allocate space for ARRAY_SIZE elements of size int[ARRAY_SIZE] and zero the memory:
int(*array1)[ARRAY_SIZE] = calloc(ARRAY_SIZE, sizeof *array1);
int(*array2)[ARRAY_SIZE] = calloc(ARRAY_SIZE, sizeof *array2);
if(array1 == NULL || array2 == NULL) exit(1);
However, by the looks of it, you don't actually need all that memory in most cases since you get length1
, width1
, length2
and width2
from the files. Allocate the arrays after you've gotten that input from the files:
if(fscanf(fp1, " %d %d", &length1, &width1) != 2 ||
fscanf(fp2, " %d %d", &length2, &width2) != 2) exit(1);
int(*array1)[width1] = calloc(length1, sizeof *array1);
int(*array2)[width2] = calloc(length2, sizeof *array2);
if(array1 == NULL || array2 == NULL) exit(1);
Then use array1
and array2
just like you did before.
When you are done with them, free
the allocated memory:
free(array1);
free(array2);