Sam
Sam

Reputation: 233

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.

Upvotes: 3

Views: 142

Answers (2)

M.M
M.M

Reputation: 141554

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

Upvotes: 2

reader
reader

Reputation: 516

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

Upvotes: 3

Related Questions