У меня есть функция, предназначенная для распределения массива и последующего заполнения его значениями из файла (n-мерные координаты, хотя пока работает в 2d).

#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);
}

Некоторые образцы данных доступны здесь.

Когда значения печатаются изнутри функции, они в порядке, когда значения печатаются вне функции - нет. Так что я не должен правильно обращаться с указателями. Возможно (а может и нет) стоит отметить, что я изначально не использовал структуру и имел функцию, определенную как double **read_and_malloc(num), возвращающую указатель на массив, и полученный результат был идентичным.

Так, что происходит?

Я могу включить некоторые образцы данных или любую другую информацию, если это необходимо.

3
Sam 3 Мар 2015 в 02:01

2 ответа

Лучший ответ

В обновленном коде вы выделяете bar->num строк и 2 столбцов. Однако ваш код fscanf и printf пытается работать с массивом с 2 строками и bar->num столбцами.

Чтобы ваш код чтения / записи оставался нетронутым, код распределения будет следующим:

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. Если вы не знакомы с этой идиомой malloc, см. Здесь

2
Community 23 Май 2017 в 10:09

Ваш второй цикл неверен:

for(int i = 0; i < dim; i++)
    bar->array[i] = (double*) malloc(dim * sizeof(double));

Вы создаете bar->num элементов, но при этом перебираете dim элементы:

bar->array = (double**) malloc(bar->num * sizeof(double*))

Цикл должен перебирать количество элементов в первом измерении: bar->num

3
reader 2 Мар 2015 в 23:04