Вопрос по fread, fwrite, c – fread'ing и fwrite'ing структура, содержащая указатели [дубликаты]

0

На этот вопрос уже есть ответ здесь:

Написание и чтение (fwrite - fread) структур с указателями 3 ответа
gcc (GCC) 4.7.0
c89

Привет,

У меня есть следующая структура, которую я пытаюсь написать и переписать.

Однако, потому что мое устройство и ресурс являются указателями. Fwrite будет читать значения указателя, а не данные. Я не могу использовать массив для устройства или ресурса. Только указатели, так как они должны быть выделены динамически.

Я выделяю всю память для элементов структуры, прежде чем писать. Здесь не показано, так как я хочу, чтобы фрагмент был коротким. И не свободенING.

В моей функции fread я выделяю память для устройства и ресурса, чтобы fread считывал эти области памяти. Однако это не сработает.

Каков наилучший способ сделать это?

Большое спасибо за любой совет

struct data {
    int id;
    int set;
    char *device;
    char *resource;
};

struct database {
    struct data **db_data;
    size_t database_rows;
    size_t database_data_size;
};

int database_write(FILE *fp, const struct database *db)
{
    rewind(fp);

    if(fwrite(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return DATABASE_ERROR;
    }

    return 0;
}

struct database* database_read(FILE *fp, size_t db_rows, size_t db_data_size)
{
    struct database *db = NULL;
    size_t i = 0;

    db = malloc(sizeof(struct database));

    db->database_rows = db_rows;
    db->database_data_size = db_data_size;
    db->db_data = malloc(sizeof(struct data) * db_rows);

    for(i = 0; i < db_rows; i++) {
        db->db_data[i] = malloc(sizeof(struct data));
        db->db_data[i]->device = malloc(db_data_size);
        db->db_data[i]->resource = malloc(db_data_size);
    }

    rewind(fp);

    if(fread(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return NULL;
    }

    return db;
}
Это не будет работать" -- почему бы и нет? Kerrek SB

Ваш Ответ

3   ответа
1

device а такжеresource может иметь переменную длину, вы должны записать размерdevice а затем данные. Сделать то же самое дляresource, Когда вы читаете их обратно, вы можете прочитать размер, затем выделить память и, наконец, прочитать значение.

1

кажется, ответили на свой вопрос, фред и фрайт, просто посмотрите на что?s в памяти и поместите это в файл. Это прекрасно работает, если выпишу вещи, которые неуказатели (например, большие массивы чисел). Это'не предназначен для написания структур с указателями.

Если этот файл имеет формат, вам нужно сделать то, что говорит формат. Если ты'По мере того, как вы создаете формат, вы должны записать каждого участника по одному в файл. Вам понадобится какой-то буфер для чтения (вам может понадобиться изменить его размер, если вы неиметь максимальную длину спецификации). Кроме того, ваша функция database_write также должна быть немного изменена.

1

Может быть, вы можете использовать поле для длины устройства и ресурса в вашей структуре "структура данных ", Создайте оболочку для fread () и fwrite (), которая читает / записывает эту длину. В этой оболочке вы можете использовать устройства memcpy, ресурс во временном буфере и использовать на нем функцию fwrite ().

Это простое и очень простое решение.

При отправке пакетов в сети вы обычно видите структуры, содержащие указатели на символы. Первые 4/8 байтов хранят длину данных, а остальные байты содержат фактические данные. Пользователь, читающий пакет, сначала читает начальные 4/8 байтов. В зависимости от этого вызывается read () для чтения оставшихся данных.

Вы можете сослатьсяЭто "структура хак " технически неопределенное поведение?

Похожие вопросы