fread'ing a binary file into a dynamically allocated C array - c

Just a quick comment to start: While there are similar threads to this one, I haven't quite been able to find the solution I'm looking for. My problem is the following:
I have 2D arrays of doulbes saved to binary files and I would like to read the binary files (using C code) into a 2D array. Additionally, I need to allocate the memory dynamically as the shape of the arrays will be changing in my application. To get started, I tried the following code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
int N = 10; //number of rows of 2D array
int M = 20; //number of columns
/* first allocate the array */
double **data;
data = (double **)malloc(N*sizeof(double *));
for(unsigned int i=0; i < N; i++) {
data[i] = (double *)malloc(sizeof(double)*M);
}
FILE *ptr;
ptr = fopen("random_real_matrix.dat", "rb");
fread(data, sizeof(data), 1, ptr);
for(unsigned int i=0; i<10;i++){
for(unsigned int j=0; j<20;j++){
fprintf(stderr, "m[%d][%d] = %f\n ", i, j, data[i][j]);
}
}
}
Unfortunately, this code segfaults. I checked to see if I can set the array entries like
d[0][0] = 235;
and that works fine.
Assuming this approach can be fixed, I'm also interested to know if it could be extended to read to an array of double complex's.
Any advice would be greatly appreciated!

Your fread statement is incorrect. It's a common beginner mistake to think that sizeof gets the size of a dynamically allocated array. It doesn't. In this case it just returns the size of a double **. You will need to read in each double in the file and put that into the correct spot in the array.
for (int ii = 0; ii < N; ++ii)
{
for (int jj = 0; jj < M; ++jj)
{
fread(data[ii][jj], sizeof(double), 1, ptr);
// Be sure to check status of fread
}
}
You can do this with a single for loop (or a single fread) but this is probably clearer to read.

Because you allocated each row separately, you can't read into the entire array at once. You need to do it row by row.
for (int i = 0; i < N; i++) {
fread(data[i], sizeof(double), M, ptr);
}

Related

Problem with free() function in C and memory-leaks

I've a problem about deallocating memory using free() in C.
My program generates a random genealogic tree using a matrix. This matrix can be very huge depending on the number of family members. The program seemed to work fine until I decided to generate more than one tree. I noticed that generating about 100 trees causes my 8GB RAM to fill! I'm sure I can make a better code to reduce the demand of memory, but my problem remains.
I use free() to deallocate memory and there's no error. I installed Valgrind to se what's happening and it says that about 100 million byte per tree are definitely lost. This means that free() doesn't work fine. I don't now where is the problem. I link some functions that I think are correlated to the problem.
typedef struct{
int f_id;
char f_name[L_NAMES];
int generations;
int n_members;
type_people *members;
int_mtx *mtx;
}type_family;
The struct above is for the family.
typedef struct temp{
int p_id;
char name[L_NAMES];
char f_name[L_NAMES];
int generation;
int n_sons;
struct temp **sons;
int f_id;
int sex;
int age;
}type_people;
This is for the members.
typedef struct{
int i;
int j;
int **val;
}int_mtx;
And the matrix.
In the main i call the function to initialize the tree:
type_family *family_a;
family_a = malloc(sizeof(type_family));
family_a = init_family_n_gen(family_a, 6);
This is the frist part of init_family_n_gen():
type_family *init_family_n_gen(type_family *family, int n){
...
family->members = malloc(max_people * sizeof(type_people));
family->mtx = mtxcalloc(family->mtx, max_people, max_people - 1);
...
This code is for mtxcalloc that initializes the matrix:
int_mtx *mtxcalloc(int_mtx *mtx, int i, int j){
mtx = malloc(sizeof(int_mtx));
mtx->i = i;
mtx->j = j;
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
return mtx;
}
And to conclude the code to deallocate the family:
void free_family(type_family *family){
for(int m = 0; m < family->n_members; m++){
if(family->members[m].n_sons != 0){
free(family->members[m].sons);
}
}
mtxfree(family->mtx);
free(family->members);
}
And the one to deallocate the matrix:
void mtxfree(int_mtx *mtx){
for(int i = 0; i < mtx->i; i++){
free(mtx->val[i]);
}
free(mtx->val);
free(mtx);
}
Screen capture of Valgrind output
So I call the free_family(family_a) every time i need to regenerate the family but the memory still increases. (In the photo above the number of byte become 1 billion if i regenerate the family for 50 times).
Thanks for the support!
EDITED
I made a minimal reproducible example that emulates my original code. The structs and variables are the same but I changed the functions according to Weather Vane: they are all void and I pass them the double **.
The init_family_n_gen becomes:
void init_family(type_family **f){
type_family *family = malloc(sizeof(type_family));
family->members = malloc(100 * sizeof(type_people));
for(int m = 0; m < 100; m++){
family->members[m].n_sons = 0;
}
mtxcalloc(&family->mtx, 100, 99);
family->mtx->val[0][1] = 7;
family->mtx->val[9][8] = 1;
mtxrealloc(&family->mtx, 5, 4);
*f = family;
}
The main is:
type_family *family_a;
init_family(&family_a);
free_family(&family_a);
The only thing I added is this function(Is the code right?):
void mtxrealloc(int_mtx **mtx, int i, int j){
(*mtx)->i = i;
(*mtx)->j = j;
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
for(int a = 0; a < (*mtx)->i; a++){
(*mtx)->val[a] = realloc((*mtx)->val[a], (*mtx)->j * sizeof(int));
}
}
I noticed that the problem occours when i use the realloc function and i can't figure why. I link the images of Valgrind with and without the function mtxrealloc. (I see that there is aslo a 48 byte leak...).
Valgrind with realloc
Valgrind without realloc
Thanks again for your support!
This:
init_family(&family_a);
Causes this code from mtxcalloc to execute:
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
, with i, j = 100, 99. That is, you allocate space for 100 pointers, and for each one, you allocate space for 99 ints. These are then accessible via family_a->mtx.
Very shortly thereafter, you make this call:
mtxrealloc(&family->mtx, 5, 4);
, which does this, among other things:
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
That loses all the pointers (*mtx)->val[5] through (*mtx)->val[99], each of which is the sole pointer to allocated space sufficient for 99 ints. Overall, sufficient space for 9405 ints is leaked before you even perform any computations with the object you are preparing.
It is unclear why you overallocate, just to immediately (attempt to) free the excess, but perhaps that's an artifact of your code simplification. It would be much better to come up with a way to determine how much space you need in advance, and then allocate only that much in the first place. But if you do need to reallocate this particular data, then you need to first free each of the (*mtx)->val[x] that will be lost. Of course, if you were going to reallocate larger, then you would need to allocate / reallocate all of the (*mtx)->val[x].

Strange behavior while filling dinamically allocated 2D char array in C

I need to create a program that plays the game Hex on a 14x14 board.
So I created, allocated and filled the board with '-' (our pattern for empty spaces).
When I try to print the board's coordinates, I don't always get '-' but some random characters.
Also, if I try to printf array[i][j] on the createBoard function after the line "board[i][j] = '-';" I get a segmentation fault right after it prints tab[8][0].
What is causing this and how can I fix it?
My code:
#include <stdio.h>
#include <stdlib.h>
char **createBoard()
{
/*Allocates a 14x14 matrix and fills it
*with '-' to create the board.*/
int i, j;
char **board;
board = malloc(14);
if (!board) exit(1);
for (i = 0; i < 14; i++){
board[i] = malloc(14);
if (!board[i]) exit (1);
for (j = 0; j < 14; j++)
board[i][j] = '-';
}
return board;
}
int main()
{
int i, j;
char **board = createBoard();
for (i = 0; i < 14; i++)
for (j = 0; j < 14; j++)
printf("tab[%d][%d]: %c\n",i, j, board[i][j]);
return 0;
}
For starters it is not clear why you don't want to declare an array instead of allocating dynamically numerous one-dimensional arrays.
As for the code then this memory allocation
board = malloc(14);
is invalid. You have to write
board = malloc( 14 * sizeof( char * ));
Also you should free all the allocated memory in the reverse order relative to its allocation before the program ends.
Take into account that it is always better to use named constants instead of magic numbers. At least you could write either
#define N 14
before main
or
const int N = 14.
and use the variable N everywhere where you are using magic number 14.
By the way according to the C Standard function main without parameters shall be declared like
int main( void )
The variable *board is a pointer, but you only allocate one byte for each array element, which should be
#define DIM 14
board = malloc(DIM * sizeof *board);
Following that up with the second allocation
board[i] = malloc(DIM * sizeof **board);
This also allows (a) that the dimension 14 is hard coded in only one place in the program and (b) the allocation will survive if you later make the board's element a different type, for example a struct, as the program develops.

Accessing array malloced inside a function from outside - unexpected results

I have a function designed to malloc an array and then fill it with values from a file (n-dimensional coordinates, although working in 2d for now).
#include <stdio.h>
#include <stdlib.h>
#define dim 2
typedef struct {
double **array; /*store the coordinates*/
int num; /* store the number of coordinates*/
/* store some other things too */
} foo;
void read_particles(foo *bar);
int main(void)
{
foo bar;
read_particles(&bar);
printf("\n");
for(int i = 0; i < bar.num; i++)
printf("%f %f\n", bar.array[0][i], bar.array[1][i]);
/* printf here does not output the array properly.
* Some values are correct, some are not.
* Specifically, the first column bar.array[0][i] is correct,
* the second column bar.array[1][i] is not, some values from the
* first column are appearing in the second.
*/
return 0;
}
void read_particles(foo *bar)
{
FILE *f = fopen("xy.dat", "r");
/* read number of coordinates from file first*/
fscanf(f, "%d", &bar->num);
bar->array = (double**) malloc(bar->num * sizeof(double*));
for(int i = 0; i < bar->num; i++)
bar->array[i] = (double*) malloc(dim * sizeof(double));
for(int i = 0; i < bar->num; i++)
{
for(int j = 0; j < dim; j++)
fscanf(f, "%lf", &(bar->array[j][i]));
/* For now, coordinates are just 2d, print them out
* The values are displayed correctly when printing here*/
printf("%f %f\n", bar->array[0][i], bar->array[1][i]);
}
fclose(f);
}
Some sample data is available here.
When the values are printed from inside the function they are fine, when printed outside the function they are not. So I must not be dealing with the pointers properly. It may (or may not) be worth noting that I originally was not using a struct and had the function defined as double **read_and_malloc(num), returning the pointer to the array, and the output produced was identical.
So what is going on?
I can include some sample data, or any other information if need be.
Your second loop is not correct:
for(int i = 0; i < dim; i++)
bar->array[i] = (double*) malloc(dim * sizeof(double));
You create bar->num elements yet you iterate over dim elements:
bar->array = (double**) malloc(bar->num * sizeof(double*))
The loop should iterate over the number of elements in the first dimension: bar->num
In the updated code you are allocating bar->num rows and 2 columns. However, your fscanf and printf code tries to work on array with 2 rows and bar->num columns.
To keep your reading/writing code intact, the allocation code would be:
bar->array = malloc(dim * sizeof *bar->array);
for (int i = 0; i < dim; ++i)
bar->array[j] = malloc(bar->num * sizeof *bar->array[j]);
NB. If you're not familiar with this malloc idiom, see here

C: Exporting large arrays with fprintf crashes compiler?

In C, I want to export a 1D array (of floats) to a CSV file to be opened by other programs. I wrote the following helper-function to do this:
#include <stdio.h>
#include <stdlib.h>
void float1DExportCSV(float *ptr, int n){
FILE *f;
f = fopen("FloatOutput.CSV", "w");
int i = 0;
for (i = 0; i < n-1; i++){
fprintf(f, "%f", ptr[i]);
fprintf(f, "%c", ',');
}
fprintf(f, "%f", ptr[n-1]);
}
I then tried to test it on an array with 10 elements, like this:
#define n 10
int main(void){
float array[n];
int i;
for(i = 0; i < n; i++){
array[i] = 4.3f*i;
}
float1DExportCSV(array, n);
return 1;
}
This works fine, and the resulting file opens correctly. Changing n to larger numbers (up to around 400,000) also works fine.
However, somewhere around the 500,000-element mark, the program simply crashes upon building. The arrays I want to export to CSV have more than 500,000 elements. Is there a robust way of doing this type of export? Is a looping fprintf method like I used above simply not a good way of exporting a large dataset?
When the array size is too large, use heap memory.
When n is too large, allocating the array on the stack causes stack overflow. At that time, allocating the memory on the heap is the answer.
Instead of
float array[n];
Use
float* array = malloc(n*sizeof(float));
Make sure to deallocate the memory. Add
free(array);
once you are done using the array.
Your problem is that local variables are allocated on the stack. If you use a static or global variable for array it will be allocated in the .bss segment. No need for malloc() or free() complexities for this simple test case.
#define n 500000
float array[n]; /* or static float array[n]; */
int main(void){
int i;
for(i = 0; i < n; i++){
array[i] = 4.3f*i;
}
float1DExportCSV(array, n);
return 1;
}

Freeing a 2-D array in C

Please bear with me as this is probably a very simple question but I am very new to C.
I am trying to malloc a specific array and then free it. However, the line:
M = malloc(N*sizeof(double *));
...doesn't work. Can somebody please explain to me why this is not working and what the solution would be? Many thanks in advance.
You should free all positions, not just the first. See this example I have wrote.
As mentioned from #Grijesh, the allocation is also wrong. The example covers allocation too. Moreover, I suggest you not to cast the return of malloc (more).
You have to think the 2D array, as a 1D array, where every cell of it is a pointer to a 1D array. A picture might help:
http://gsamaras.files.wordpress.com/2014/04/array2d-n.png
Here, 1D array that holds the pointers is to the left and every cell of it, points to another 1D array.
How many 1D arrays to the left? As many cells as you have in the left array.
Btw, Nelly I think this is not a silly question, it's something that gets beginners into trouble. ;)
EDIT:
About your new code, you had to have the same definition and declaration for matrix_free, as well as, call it as you should. What's definition, etc. ?? Answer.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define Nmax 9000
double **makeMatrix(int N);
void free_matrix(double **M,int N);
int main(void) {
int N;
for (N = 2; N < Nmax; N *= 2) {
double **L = makeMatrix(N);
printf("yes \n");
free_matrix(L, N);
printf("woo \n");
}
return 0;
}
double **makeMatrix(int N) {
int i, j;
double **M;
M = malloc(N * sizeof(double *));
for (i = 0; i < N; i++)
M[i] = malloc(N * sizeof(double));
for (i = 1; i < N; i++) {
for (j = 1; j < N; j++) {
M[i][j] = (i) * (j) * M_PI / N;
}
}
return (M);
}
void free_matrix(double **M, int N) {
int i;
for (i = 1; i <= N; i++) {
free(M[i]);
}
free(M);
}
And then I receive the youwho output. :) But, it will stop at a certain point, because NMAX is too big! Not only NMAX is too big, but N grows really fast ( N *=). Have you done the math in a piece of paper? Too big numbers. For example, if I do N +=, then, I can go until NMAX = 9000.
Debug tip:
How do I know in which loop it reaches?
I printed out the counter of the loop, like this
printf("woo %d\n",N);
Of course, if you feel sure for yourself, then I suggest you learning the debugger.

Resources