fwrite не может записать большие данные - PullRequest
2 голосов
/ 14 декабря 2011

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

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    int size = atoi(argv[1]);
    printf("%d\n", size);
    FILE* fp = fopen("test", "wb");
    char* c = "";
    int i = fwrite(c, size, 1, fp);
    fclose(fp);
    printf("%d\n", i);
    return 0;
}

Код скомпилирован в двоичный файл tw Когда я пытаюсь ./tw 10000, это работает хорошо. Но когда я пытаюсь что-то вроде ./tw 12000, это терпит неудачу. (Fwrite () возвращает 0 вместо 1) В чем причина этого? Каким образом я могу избежать этого?

РЕДАКТИРОВАТЬ: Когда я делаю fwrite (c, 1, size, fp), он возвращает 8192 вместо большего размера, который я даю.

2-е РЕДАКТИРОВАНИЕ: Когда я пишу цикл, который выполняется для размера раз и fwrite(c, 1, 1, fp) каждый раз, он прекрасно работает. Кажется, когда size слишком велик (как в первом EDIT), он записывает только около 8192 байтов. Я предполагаю, что что-то ограничило fwrite запись до байтов фиксированного размера за раз.

3-е РЕДАКТИРОВАНИЕ: Выше не ясно. Следующее не выполняется для space - w_result != 0, когда пространство велико, где пространство определяется мной, а w_result - это объект, написанный полностью.

w_result = 0;
char* empty = malloc(BLOCKSIZE * size(char));
w_result = fwrite(empty, BLOCKSIZE, space, fp);
printf("%d lost\n", space - w_result); 

Пока все работает нормально.

w_result = 0;
char* empty = malloc(BLOCKSIZE * sizeof(char)); 
for(i = 0; i < space; i ++)
    w_result += fwrite(empty, BLOCKSIZE, 1, fp);
printf("%d lost\n", space - w_result);

(каждая переменная была объявлена).

Я исправил некоторые ошибки, которые запомнили ответы. Но первый должен работать в соответствии с вами.

Ответы [ 4 ]

2 голосов
/ 14 декабря 2011

С fwrite(c, size, 1, fp); вы заявляете, что fwrite должен записать 1 элемент, который size большой, большой из буфера c.

c это просто указатель на пустую строку. Он имеет размер 1. Когда вы указываете fwrite искать больше данных, чем 1 байт в c, вы получаете неопределенное поведение. Вы не можете записать более 1 байта из c.

(неопределенное поведение означает, что что-то может произойти, может показаться, что оно работает нормально при попытке с размером 10000, а не с размером 12000. Причиной, зависящей от реализации, вероятно, является наличие некоторой доступной памяти, возможно, стек, начиная с c и 10000 байт вперед, но, например, с 11000 нет памяти, и вы получаете segfault)

2 голосов
/ 14 декабря 2011

Вы читаете память, которая не принадлежит вашей программе (и записываете ее в файл).

Проверьте свою программу, используя valgrind, чтобы увидеть ошибки.

1 голос
/ 14 декабря 2011

Как было сказано другими, код выполняет недопустимое чтение из памяти через c.

Возможным решением будет динамическое выделение буфера размером size байтов, его инициализация,и fwrite() в файл, не забывая впоследствии освободить буфер.

Не забудьте проверить возвращаемые значения из функций (например, fopen()).

1 голос
/ 14 декабря 2011

Из этого фрагмента кода похоже, что вы пытаетесь записать то, что находится в c, который представляет собой всего один NULL-байт, в указатель файла, и вы делаете это "размер" раз. Тот факт, что он не падает с 10000, является случайным. Что ты пытаешься сделать?

...