'Dynamic memory in c, change size of array
I have a doubt, how can i solve this?
I have a file with several matrices, and I need to use while a loop like this. I just know the order of the array when the file is read.
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <stdbool.h>
int MIN_ORDER = 32;
int M = 0;
int N = 0;
bool firstProcessing = true;
int pos=0;
typedef struct {
int numberOfMatrices;
int orders;
int nextMatrixToProcessed;
bool done;
} INFOSFILE;
int getMatrix(double buffer[N][N], INFOSFILE *infos, int *min_size) {
FILE *f = fopen("src/128_32.bin", "rb+");
if(f == 0) {
perror("fopen");
exit(1);
}
if (firstProcessing) {
fread(&M,sizeof(M),1,f);
fread(&N,sizeof(N),1,f);
pos = ftell(f);
infos->nextMatrixToProcessed = 0;
infos->numberOfMatrices = M;
infos->orders = N;
infos->done = false;
firstProcessing = false;
} else{
if (infos->done) return 1;
}
*min_size = N;
if (infos->nextMatrixToProcessed +1 == infos->numberOfMatrices ){
infos->done = true;
}
if (firstProcessing == false) fseek(f, pos, SEEK_SET );
if (firstProcessing == true) firstProcessing = false;
fread(buffer, sizeof(double[N * N]), 1, f);
pos = ftell(f);
fclose(f);
return 0;
}
void processMatrix(double buffer[N][N], INFOSFILE *infos){
printf("Matrix %d\n",infos->nextMatrixToProcessed);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%f\t", buffer[i][j]);
}
printf("\n");
}
printf("\n\n");
infos->nextMatrixToProcessed++;
}
int main(int argc, char *argv[]) {
setlocale(LC_CTYPE, "");
double buffer[MIN_ORDER][MIN_ORDER];
INFOSFILE infos;
while (getMatrix( buffer, &infos, &MIN_ORDER) != 1) {
processMatrix(buffer, &infos);
}
printf("\n%d",infos.nextMatrixToProcessed);
printf("\n%i",infos.done);
printf("\n%d",infos.numberOfMatrices);
printf("\n%d",infos.orders);
return 0;
}
I can't change the algorithm, only i can change the declarations.
The file has: Number of matrices Matrix order Matrix[1] Matrix[2] ...
Solution 1:[1]
- For a given input file with float/double values like : Three matrices of different sizes:
3
2 3
1.0 2.0 3.0
4.0 5.0 6.0
4 4
1.0 2.0 3.0 3.5
4.0 5.0 6.0 6.5
1.2 2.2 3.5 6.5
9.5 5.5 5.4 6.4
2 2
123.211 353.54
5455.878 587.545
- You can dynamically
realloc()memory needed as follows:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
static inline void
matrix_print (int rows, int cols, double dmat[rows][cols]) {
for (int ri = 0; ri < rows; ++ri) {
for (int ci = 0; ci < cols; ++ci)
printf ("%6.2lf\t", dmat[ri][ci]);
putchar ('\n');
}
}
void /* rows & cols should precede dmat in argument list */
matrix_read (FILE* mFile, int rows, int cols, double dmat[rows][cols]) {
for (int ri = 0; ri < rows; ++ri)
for (int ci = 0; ci < cols; ++ci)
if (1 != fscanf (mFile, " %lf", &dmat[ri][ci])) {
printf ("ERROR reading matrix\n"); exit (5);
}
}
int main() {
FILE* mFile = fopen ("input.txt", "r");
if (!mFile) {
perror ("Opening File"); return 1;
}
int count;
if (1 != fscanf (mFile, " %d", &count)) {
printf ("ERROR: fscanf-count\n"); return 2;
}
double (*dmat)[1] = malloc (sizeof(dmat[0][0]));
while (count--) {
int rows, cols;
if (2 != fscanf (mFile, " %d %d", &rows, &cols)) {
printf ("ERROR: fscanf-rows-cols\n"); return 3;
}
dmat = realloc (dmat, sizeof(double[rows][cols]));
if (!dmat) {
perror("mat-memory-alloc"); return 4;
}
matrix_read(mFile, rows, cols, dmat);
// malloc_usable_size() is from GNU extensions
printf ("\n\nMemory Alloc'd to double-dMat[%d][%d] : %zu\n", rows, cols, malloc_usable_size(dmat));
matrix_print(rows, cols, dmat);
}
if (dmat) free (dmat);
fclose (mFile);
return 0;
}
- You can also use
free()&malloc()combo, sincerealloc()is expensive trying to preserve existing data.
free (dmat);
dmat = malloc (sizeof(double[rows][cols]));
- You can also make use of
Variabl-Length-Arrayif matrix data is small (less than a million entries for 8 MiB process-stack).
while (count--) {
int rows, cols;
if (2 != fscanf (mFile, " %d %d", &rows, &cols)) {
printf ("ERROR: fscanf-rows-cols\n"); return 3;
}
// resized at run-time : as rows & cols vary
double dmat[rows][cols];
matrix_read(mFile, rows, cols, dmat);
printf ("\n\ndouble-dMat[%d][%d] :\n", rows, cols);
matrix_print(rows, cols, dmat);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
