выделить хранилище и двоичные шорты fwrite в c - PullRequest
1 голос
/ 14 февраля 2012

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

#define CHUNK_SIZE 1000
void xwriteStructuresToFile(FILE *file, void * structureData)
{
    assert((fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE);

}

void wwbuildPtxFiles(void)
{   
    FILE *file = fopen("s:\\tv\\run32\\junky.bin", WRITE_BINARY);
    int count = 10;
    short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short ) );

    memset(ptx, '3', sizeof(short) * CHUNK_SIZE * count);
    for (int dayIndex = 0; dayIndex < count; ++dayIndex)
        xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

    free(ptx);
    fclose(file);

    file = fopen("s:\\tv\\run32\\junky.bin", READ_BINARY);
    int xcount = CHUNK_SIZE * count * sizeof(short );
    for (int i = 0; i < xcount; ++i)
    {
        char x;
        if ((x = getc(file)) != '3')
            assert(false);
    }
}

Ответы [ 5 ]

2 голосов
/ 14 февраля 2012

Удалить sizeof (short) из индекса массива.C сделает этот расчет за вас

1 голос
/ 14 февраля 2012

Несколько вещей:

как вы открываете файл, я не уверен насчет ваших констант, но они должны читать

"wb", чтобы записать двоичный файл, и "rb" дляread.

Никогда не помещайте оператор в assert, assert удаляется, когда программа компилируется в режиме выпуска.Вместо этого проверьте возвращаемое значение и подтвердите на этом

например


bool ok =fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE;
assert(ok);

, хотя вы не должны утверждать это, вместо этого вы должны распечатать правильное сообщение об ошибке. assert для ошибок программирования, а не ошибок времени выполнения .


short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short ) );

в приведенной выше строке содержится ряд проблем:

  • никогда не приводите возвращаемое значение calloc в C. short *ptx = calloc... должно быть достаточно, если вы получите предупреждение, #include <stdlib.h>

  • вы должны использоватьформа calloc( count, CHUNK_SIZE * sizeof( short )); иначе выглядит немного неясно.(calloc принимает число, размер в качестве аргументов)


   for (int dayIndex = 0; dayIndex < count; ++dayIndex)
      xwriteStructuresToFile(file, 
         (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

не уверен, что вы там делаете, замените два оператора на


fwrite( ptx, CHUNK_SIZE * sizeof( short ), count, fp );


, что должно записать весь массив.

1 голос
/ 14 февраля 2012

Вы записываете «данные» за конец массива!

xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

Вы должны использовать:

xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);

Компилятор C автоматически масштабируется на sizeof(short). Если у вас есть массив целых чисел, вы не пишете array[i * sizeof(int)] для доступа к элементу i th массива; аналогично, здесь вам не нужно масштабировать индекс на sizeof(short). В самом деле, крайне важно, чтобы вы этого не делали, потому что вы пишете дважды (исходя из предположения, что sizeof(short) == 2) так далеко в памяти, как вы ожидали.

Вы также не должны использовать assert() вокруг вызова функции, которая должна быть выполнена. Вы используете assert() в отдельном операторе, который может быть исключен из программы без ущерба для его функции. Это обсуждается довольно подробно в «Написание твердого кода» Стивом Магуайром, который немного устарел в некоторых местах, но, по крайней мере, звучит по этому вопросу.

1 голос
/ 14 февраля 2012

При звонке на xwriteStructuresToFile вы используете:

&ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]

ptx - короткий указатель, то есть вычисления массива автоматически будут масштабированы до размера короткого.

Явно сделав это и в вышеприведенном выражении, вы выйдете далеко за пределы массива. Вам нужно заменить эту строку на что-то вроде:

xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);
0 голосов
/ 14 февраля 2012

Поскольку ptx является указателем short *, вы не должны умножаться на sizeof(short) при его индексации.Индекс уже в единицах short с, поэтому вы хотите:

xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * dayIndex ]);
...