- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:13 , 24-Ноя-08 (1)>buffer = (char*) malloc (sizeof(char)*lSize); тут бы if (!buffer) perror(""); все проверки всех действий сделаны, везде? >result = fread (buffer,1,lSize,pFile); по ману fread надо еще проверять ошибку и конец файла через feof(), ferror() если выше в malloc() для чаров sizeof() делаем, то и тут sizeof(char) для единообразия писать надо вместо 1 :) >if ( result != lSize) {fputs ("Reading error\n",stderr); } по мелочи: fprintf(stderr,""); // уже идиома, не цепляет глаз и читается проще чем fputs() + strace(), dbg, так же обратить внимание на ключи оптимизации и т.п. а то сравнение не работающее для одиноковых чисел - вроде смахивает на убитый стек.
- C/C++ 64bit. Глюк при сравнении чисел,
yerdna, 00:43 , 25-Ноя-08 (2)Vic спасибо за внимание.>тут бы if (!buffer) perror(""); >все проверки всех действий сделаны, везде? Да, просто не стал засарять форум. >по ману fread надо еще проверять ошибку и конец файла через feof(), Говорит что конец файла не достигнут, хотя на самом деле он все считал в память. >ferror() ошибок нет. >если выше в malloc() для чаров sizeof() делаем, то и тут sizeof(char) >для единообразия писать надо вместо 1 :) Учту. >по мелочи: fprintf(stderr,""); // уже идиома, не цепляет глаз и читается проще >чем fputs() Тоже учту >+ strace(), dbg, так же обратить внимание на ключи оптимизации и т.п. >а то сравнение не работающее для одиноковых чисел - вроде смахивает >на убитый стек. Strace работает только на i386 у меня ядро amd64. dbg запускал, но только ничего не нашел, наверно я неумют ею пользоваться. Я забыл написать, что система у меня 64битная. (freebsd amd64) Сегодня когда выводил через printf числа, указал формат %lu и вот что получилось lSize = 2205089792 result = 18446744071619674112 а когда указываю формат %u ,то в обеих 2205089792 Может есть какие-то идеи?
- C/C++ 64bit. Глюк при сравнении чисел,
angra, 01:16 , 25-Ноя-08 (3)Есть мысль что вам нужно прочитать наконец про машинное представление чисел, особенно знаковых.
- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:07 , 25-Ноя-08 (4)>Есть мысль что вам нужно прочитать наконец про машинное представление чисел, особенно >знаковых. И включить -Wall чтобы gcc на printf() вываливал варнинг по поводу несоответствия спецификатора и типа выводимого значения. Помогает даже если в курсе, но случайно ошибся :)
- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:14 , 25-Ноя-08 (5)>Может есть какие-то идеи? посмотреть sizeof(size_t), sizeof(off_t) и почитать про включение поддержки больших файлов для freebsd, а то если они 8 байт (так скорее всего и есть), то больше 2ГБ ну никак :)
- C/C++ 64bit. Глюк при сравнении чисел,
SunRock, 22:56 , 26-Ноя-08 (6)>посмотреть sizeof(size_t), sizeof(off_t) >а то если они 8 байт (так скорее всего и есть), то больше 2ГБ ну никак :) 8589934592 GB математик хренов :)
- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:21 , 27-Ноя-08 (7)>>посмотреть sizeof(size_t), sizeof(off_t) >>а то если они 8 байт (так скорее всего и есть), то больше 2ГБ ну никак :) > >8589934592 GB математик хренов :) в хренах именно столько
- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:40 , 27-Ноя-08 (8)>>>посмотреть sizeof(size_t), sizeof(off_t) >>>а то если они 8 байт (так скорее всего и есть), то больше 2ГБ ну никак :) >> >>8589934592 GB математик хренов :) > >в хренах именно столько в том смысле что если они не 8, а 4 байта, я ступил =)
- C/C++ 64bit. Глюк при сравнении чисел,
Michelnok, 03:08 , 28-Ноя-08 (10)> >Я забыл написать, что система у меня 64битная. (freebsd amd64) >Сегодня когда выводил через printf числа, указал формат %lu и вот что >получилось >lSize = 2205089792 >result = 18446744071619674112 >а когда указываю формат %u ,то в обеих 2205089792 > >Может есть какие-то идеи? Количество считанных из файла байт потрясает. Дайте мне два таких винта :) Переменные типа size_t выводи с форматом %zu
- C/C++ 64bit. Глюк при сравнении чисел,
Michelnok, 02:58 , 28-Ноя-08 (9)>size_t lSize, result; >... >lSize = ftell (pFile); Попробуй еще off_t lSize; ... lSize = ftello (pFile);
- C/C++ 64bit. Глюк при сравнении чисел,
yerdna, 12:05 , 28-Ноя-08 (11)>>size_t lSize, result; >>... >>lSize = ftell (pFile); > >Попробуй еще > >off_t lSize; >... >lSize = ftello (pFile); Пробывал, ничего не изменилось. >Количество считанных из файла байт потрясает. Дайте мне два таких винта :) >Переменные типа size_t выводи с форматом %zu И при таком раскладе все тоже самое result = 18446744071619674112 >И включить -Wall чтобы gcc на printf() вываливал варнинг по поводу несоответствия >спецификатора и типа выводимого значения. Все соответствует, Wall молчит как рыба. ---------- Повторюсь: все работает так как надо, ошибки не выскакивают, то что я загрузил в память я потом с легкостью записываю обратно на винт, без всяких потерь данных. Просто выскакивает такой глюк, если размер файла больше ~2гиг. Единственный минус, так это то, что нельзя проверить сколько он считал. Но как вариант я уже думаю просто форматировать result через sprintf c %u. Кстати где-то вычитал, что feof() в таком месте не будет работать в любом случаи. Весь инет облазил, толком ничего и не нашел как исправить этот глюк с fread.
- C/C++ 64bit. Глюк при сравнении чисел,
vic, 14:29 , 28-Ноя-08 (12)>[оверквотинг удален] >>>... >>>lSize = ftell (pFile); >> >>Попробуй еще >> >>off_t lSize; >>... >>lSize = ftello (pFile); > >Пробывал, ничего не изменилось. fseeko() & ftello() одновременно, одного не достаточно (ессно с off_t). тип фс? для теста что будет если ручками в шелле создать файл >2GB и скопировать его? т.к. у вас фря, а у меня линукс, проверить я на коленке ничего не могу, но могу посмотреть ман для фри выложенный на опеннет, вижу что возвращаемое/устанавливаемое значение оффсета имеет тип long (возможно ман на опеннете безнадежно устарел), а не size_t. off_t судя по замечаниям в других манах (для lseek русский ман здесь же на опеннете) может быть int (4 byte, !8 byte), а lseek используется в fseek. Т.е. необходимо с файлами более 2 ГБ очень аккуратным. где-то все же ошибка у нас с вами, даже если кажется что считывается все вроде бы правильно... переменная errno после каждой операции проверяется?
- C/C++ 64bit. Глюк при сравнении чисел,
Michelnok, 16:13 , 28-Ноя-08 (14)>>Переменные типа size_t выводи с форматом %zu > >И при таком раскладе все тоже самое >result = 18446744071619674112 Если это действительно сразу после fread (т.е. ты совсем ничего не делаешь с result), то похоже таки на ошибку в libc. Точнее, в твоей ее версии.
- C/C++ 64bit. Глюк при сравнении чисел,
yerdna, 21:24 , 28-Ноя-08 (15)Наконец-то выяснил в чем проблема!) Конечно же не без вашей помощи, всем спасибо, особенно Michelnok и vic!!!Рассказываю в чем проблема: >Если это действительно сразу после fread (т.е. ты совсем ничего не делаешь >с result), то похоже таки на ошибку в libc. Точнее, в >твоей ее версии. После этого поста, я решил проверить, что же на самом деле делает fread. Открыл /usr/src/lib/libc/stdio/fread.c и что я вижу ......... size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { int ret; //ВНИМАНИЕ СЮДА FLOCKFILE(fp); ret = __fread(buf, size, count, fp); FUNLOCKFILE(fp); return (ret); //ВНИМАНИЕ СЮДА } size_t __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { size_t resid; char *p; int r; //ВНИМАНИЕ СЮДА size_t total; /* * The ANSI standard requires a return value of 0 for a count * or a size of 0. Peculiarily, it imposes no such requirements * on fwrite; it only requires fread to be broken. */ if ((resid = count * size) == 0) ......... while (resid > (r = fp->_r)) { (void)memcpy((void *)p, (void *)fp->_p, (size_t)r); fp->_p += r; /* fp->_r = 0 ... done in __srefill */ p += r; resid -= r; //ВНИМАНИЕ СЮДА if (__srefill(fp)) { /* no more input: return partial result */ return ((total - resid) / size); } } ......... return (count); } ----------------------- что функция возвращает переменную типа int, ХОТЯ в функции объявленно, что возвращаем тип size_t, отсюда понятно почему файлы больше 2гиг, а это больше 2 147 483 648, возвращал что-то страшное. После исправления int на size_t, все заработало. Често говоря, я удивлен, что разработчики freebsd допустили такую ошибку(size_t -> int).
- C/C++ 64bit. Глюк при сравнении чисел,
Michelnok, 22:01 , 28-Ноя-08 (16)>[оверквотинг удален] > int ret; //ВНИМАНИЕ СЮДА > > > FLOCKFILE(fp); > ret = __fread(buf, size, >count, fp); > FUNLOCKFILE(fp); > return (ret); //ВНИМАНИЕ СЮДА > >} Ужас.
|