Вывод и ввод двоичных данных C - PullRequest
0 голосов
/ 08 января 2012

Я пытаюсь вывести и ввести двумерный массив в двоичный файл.

Мой двумерный массив содержится в следующей структуре

typedef struct matrep {
    unsigned rows, columns;
    double *data;
} MATRIX;

и я создал следующую функцию для вывода всей структуры

void matrix_writebinary(MATRIX *mat,FILE *fp)     
{
    int a=mat->rows,b=mat->columns;
    fwrite(&a,sizeof(int),1,fp);
    fwrite(&b,sizeof(int),1,fp);
    fwrite(mat->data,sizeof( double ) * a * b,1,fp);
    rewind(fp);
}

и следующая функция для ввода структуры

MATRIX *matrix_readbinary(MATRIX *mat,FILE *fp)     
{
    MATRIX matrix;
    MATRIX *ptr;
    ptr=&matrix;
    int a,b;

    double *tempptr=ptr->data;
    fread(&a,sizeof(int),1,fp);
    fread(&b,sizeof(int),1,fp);

    for ( int i=0; i < a; i++ )
    {
        for ( int j=0; j < b; j++ )
        {
            double value=0.0;     
            fread(&value,sizeof(double),1,fp);
            *(tempptr++)=value;
        }
    }

    rewind(fp);
    matrix.rows=a;
    matrix.columns=b;
    return(ptr);
}

Я проверил, что mat->rows и mat->columns были правильно введены и выведены с использованием функции printf, но когда она достигает линии

*(tempptr++)=value;

в коде я получаю ошибку сегментации, которая говорит мне, что я путаю мои указатели. Я не думаю, что проблема заключается в открытии закрытия или манипулировании файлами вне функции, так как я успешно вывел файл и ввел его с помощью fprintf и fscanf.

Может ли кто-нибудь помочь мне разобраться с моими указателями?

1 Ответ

4 голосов
/ 08 января 2012

Вы не выделили никакой памяти для данных. Вам необходимо добавить распределение:

ptr->data = malloc(sizeof(double) * ptr->rows * ptr->columns);
double *tempptr = ptr->data;

/* ... */

Кроме того, вы не должны возвращать временный адрес! Таким образом, сама матрица также должна быть размещена динамически:

MATRIX * ptr = malloc(sizeof(MATRIX));

Вы можете читать в &ptr->rows и &ptr->columns напрямую, нет необходимости в промежуточных переменных. Вы также можете прочитать все данные за один раз.

Собираем все вместе:

MATRIX *matrix_readbinary(FILE * fp)
{
    MATRIX * ptr = malloc(sizeof(MATRIX));

    fread(&ptr->rows, sizeof(unsigned int), 1, fp)
    fread(&ptr->columns, sizeof(unsigned int), 1, fp)

    ptr->data = malloc(sizeof(double) * ptr->rows * ptr->columns);

    fread(ptr->data, sizeof(double), ptr->rows * ptr->columns, fp)

    return ptr;
}

Я бы не рекомендовал передавать указатель MATRIX, поскольку это потребовало бы, чтобы вы предоставили некоторую структуру полуобработанной матрицы без выделенной памяти данных, и вы оказались бы в кошмаре ответственности.

Не забудьте соответствующую функцию очистки:

void matrix_free(MATRIX * mat)
{
    free(mat->data);
    free(mat);
}
...