Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 02.03.05 01:20
Оценка:
Здравствуйте.
Помогите разобраться.
Программа считывает файл в буфер. Вывод на экран из буфера.
Программа должна осуществить замер времени от начала считывания из файла до момента вывода на экран последнего символа.
Имя файла и размер буфера задается с командной строки как параметры. Буфер 1Кб, 10Кб, 20Кб и т.д. до 64Кб.
Не могу понять в чем дело. В тексте я пометил подозрительную строку как /*???*/. Вот если на ней установить breakPoint, то выдается ошибка — invalid BreakPoint и эта строка игнорируется вообще в программе.
Если же в этой строке указать функцию _read(...), то ошибка — invalid BreakPoint не выдается.
Далее. Считывание файла проходит более менее нормально при размерах буфера до 30Кб,
При 40Кб получаем.
bytes = read(handle,buf,sbuf)

равно нулю или отрицательному значению. В чем дело?
Пробовал на файлах разного размера от 61Кб до 15Мб.
Посоветуйте что делать.Спасибо.

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <io.h>
#include <alloc.h>
#include <time.h>
#include <FCNTL.H>

 int main(int argc, char ** argv)

{
    /* Переменные для работы с файлом */
    int handle;
    long bytes;
    char *buf;
    long sbuf;

    /* Переменные для подсчета времени */
    time_t tm1, tm2;

    clrscr(); // очистка экрана

  /* Открываем файл */
    if ((handle = open(_argv[1], O_RDONLY)) == -1)
        {
         printf("Error Opening File\n");
         return -1;
        };

  /* Определяем размер буфера */
      sbuf = (atoi(_argv[2]));
      sbuf*=1024;

      if((buf = new(char[sbuf]))==NULL)
        {
         printf("Not enough memory to allocate buffer\n");
         return -1;
        };

        tm1 = time(NULL);
/*??? см.тут*/     bytes = read(handle,buf,sbuf);

        while(bytes>0)
        {
         printf(buf);
         bytes = read(handle,buf,sbuf);
        };

        tm2 = time(NULL);

        delete(buf);
        close(handle);

        printf("\n\n==============================================");
        printf("\nРазмер буфера: %ld kb",sbuf/1024);
        printf("\nВремя обработки: %ld сек.",tm2-tm1);

    return 0;
}
Re: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 04:25
Оценка:
Это потому, что функция read объявлена как int read, хотя значения возвращает в пределах unsigned int и должна быть объявлена unsigned int read. И совершенно понятно, что при буфере <=32 КБ проблем не возникнет. Соответственно, чтобы получить значение bytes тебе надо писать bytes = (unsigned int)read(...); В том случае, если (signed int)bytes == -1, выводить ошибку. Ну или по-другому можно if (bytes == 0x0000FFFF). Ну а ноль всегда останется нулем... По поводу точки останова ничего сказать не могу...
Re: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 04:26
Оценка:
А вообще, лучше используй стандартные fopen, fread и т.д.
Re[2]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 02.03.05 05:02
Оценка:
Здравствуйте, ansi, Вы писали:

A>А вообще, лучше используй стандартные fopen, fread и т.д.

Мда... если бы знать эти стандартные. Я сделал так только потому,
что нашел примеры в хелпе. А вот как правильно надо, чтобы работало
корректно — кто бы знал как.
Спасибо за помощь. Буду ковыряться дальше. На Паскале уже давно бы сделал
Re: Не могу понять этот Borland C++ 3.1
От: Аноним  
Дата: 02.03.05 07:03
Оценка:
Здравствуйте, Egor, Вы писали:

E>Здравствуйте.

E>Помогите разобраться.
E>Программа считывает файл в буфер. Вывод на экран из буфера.
E>Программа должна осуществить замер времени от начала считывания из файла до момента вывода на экран последнего символа.
E>Имя файла и размер буфера задается с командной строки как параметры. Буфер 1Кб, 10Кб, 20Кб и т.д. до 64Кб.
E>Не могу понять в чем дело. В тексте я пометил подозрительную строку как /*???*/. Вот если на ней установить breakPoint, то выдается ошибка — invalid BreakPoint и эта строка игнорируется вообще в программе.
E>Если же в этой строке указать функцию _read(...), то ошибка — invalid BreakPoint не выдается.
E>Далее. Считывание файла проходит более менее нормально при размерах буфера до 30Кб,
E>При 40Кб получаем.
E>
E>bytes = read(handle,buf,sbuf) 
E>

E>равно нулю или отрицательному значению. В чем дело?
E>Пробовал на файлах разного размера от 61Кб до 15Мб.
E>Посоветуйте что делать.Спасибо.

E>
E>#include <stdio.h>
E>#include <stdlib.h>
E>#include <dos.h>
E>#include <conio.h>
E>#include <io.h>
E>#include <alloc.h>
E>#include <time.h>
E>#include <FCNTL.H>

E> int main(int argc, char ** argv)

E>{
E>    /* Переменные для работы с файлом */
E>    int handle;
E>    long bytes;
E>    char *buf;
E>    long sbuf;

E>    /* Переменные для подсчета времени */
E>    time_t tm1, tm2;

E>    clrscr(); // очистка экрана

E>  /* Открываем файл */
E>    if ((handle = open(_argv[1], O_RDONLY)) == -1)
E>        {
E>         printf("Error Opening File\n");
E>         return -1;
E>        };

E>  /* Определяем размер буфера */
E>      sbuf = (atoi(_argv[2]));
E>      sbuf*=1024;

E>      if((buf = new(char[sbuf]))==NULL)
E>        {
E>         printf("Not enough memory to allocate buffer\n");
E>         return -1;
E>        };

E>        tm1 = time(NULL);
E>/*??? см.тут*/     bytes = read(handle,buf,sbuf);

E>        while(bytes>0)
E>        {
E>         printf(buf);
E>         bytes = read(handle,buf,sbuf);
E>        };

E>        tm2 = time(NULL);

E>        delete(buf);
E>        close(handle);

E>        printf("\n\n==============================================");
E>        printf("\nРазмер буфера: %ld kb",sbuf/1024);
E>        printf("\nВремя обработки: %ld сек.",tm2-tm1);

E>    return 0;
E>}

E>


Доброго !
В какой модели скомпилено.. Large, Huge?
Файл в текстовом режиме открыли.
lseek на начало не сделали(на всякий случай)

Когда-то на борланде делал подобное, но чтение огранизовал по другому, только не помню зачем

int h_from;
unsigned bait;
long length;
char* vBlock;
unsigned blockSize;

.................

length=filelength(h_from);
if (length>blockSize)
bait=read(h_from,vBlock,blockSize); /* Количество байт в блоке */
else
bait=read(h_from,vBlock,length); /* Количество байт в блоке */
while (bait > 0)
{
....................
length-=bait;
if (length>blockSize)
bait=read(h_from,vBlock,blockSize);
else
bait=read(h_from,vBlock,length);
}


С уважением.
Re[3]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 07:14
Оценка:
E>Мда... если бы знать эти стандартные. Я сделал так только потому,
E>что нашел примеры в хелпе. А вот как правильно надо, чтобы работало
E>корректно — кто бы знал как.
Не знаю как ты ищешь. Help -> Index -> fopen. Использование open, read не является некорректным, просто это все от Борланда, а fopen, fread — из стандарта Си и поддерживаются всеми компиляторами.

E>Спасибо за помощь. Буду ковыряться дальше. На Паскале уже давно бы сделал

Да, C/C++ с первого взгляда не подарок, но когда его поймешь (если поймешь)... Просто почитай, как хранятся числа в двоичной системе, про дополнительный код, ... Тогда ты поймешь, почему оно у тебя не работало. А знать это в любом случае надо.
Re[2]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 07:19
Оценка:
А>length=filelength(h_from);
А>if (length>blockSize)
А> bait=read(h_from,vBlock,blockSize); /* Количество байт в блоке */
А>else
А> bait=read(h_from,vBlock,length); /* Количество байт в блоке */

Вот здесь ты можешь вылететь в бесконечный цикл. bait у тебя unsigned, а значит, что если read вернет ошибку -1, в твоем случае это будет 65535, что больше нуля. Функция read может считать максимум 65534 байт за раз, не больше.

А>while (bait > 0)

А>{
А>....................
А>length-=bait;
А>if (length>blockSize)
А> bait=read(h_from,vBlock,blockSize);
А>else
А> bait=read(h_from,vBlock,length);
А>}


А>С уважением.
Re[3]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 02.03.05 07:24
Оценка:
Здравствуйте, ansi, Вы писали:

A>Вот здесь ты можешь вылететь в бесконечный цикл. bait у тебя unsigned, а значит, что если read вернет ошибку -1, в твоем случае это будет 65535, что больше нуля. Функция read может считать максимум 65534 байт за раз, не больше.


Ну, а как же прочитать в буфер размером 64Кб, что равно 65535 ??
Re[2]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 02.03.05 07:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В какой модели скомпилено.. Large, Huge?


Small установлено. В какой надо-то? Я в этом нибельмеса.
Re[4]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 08:06
Оценка:
E>Ну, а как же прочитать в буфер размером 64Кб, что равно 65535 ??
На самом деле 64Кб — это 65536, не так ли? То есть ты можешь считать на два байта меньше, чем тебе надо Грустно, не правда?
64Кб ты возможно сможешь считать, если будешь использовать fread.
Она описана так:
size_t fread( 
   void *buffer,
   size_t size,
   size_t count,
   FILE *stream 
);


Если sizeof(size_t) равен 4 (т.е. size_t — это long), то ты сможешь это сделать. Если же равен 2, то тогда с ее помощью ты считаешь на один байт больше — 65535 байт. Это легко проверить — printf("%d", sizeof(size_t));
Если бы ты писал под Win, то там само собой int четырехбайтный, а вот под дос...
Re[3]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 08:33
Оценка:
E>Small установлено. В какой надо-то? Я в этом нибельмеса.
Это никак не повлияет. Кстати, я проверил — size_t равен 2. Так что 64Кб тебе не светят на 16-битном BC++ 3.1, впрочем как и на 16-битном Паскале...
Re[3]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 02.03.05 08:49
Оценка:
Хотя это я погорячился. Приведу еще раз:
size_t fread( 
   void *buffer,
   size_t size,
   size_t count,
   FILE *stream 
);


fread читает size*count байт и возвращает count (если все прошло нормально).
Тебе достаточно сделать вызов fread(buf, 1024, 64, f);
Остается как-то выделить 64Кб памяти...
Re[4]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 03.03.05 00:07
Оценка:
Здравствуйте, ansi, Вы писали:

A>Хотя это я погорячился. Приведу еще раз:

A>
A>size_t fread( 
A>   void *buffer,
A>   size_t size,
A>   size_t count,
A>   FILE *stream 
A>);
A>


A>fread читает size*count байт и возвращает count (если все прошло нормально).

A>Тебе достаточно сделать вызов fread(buf, 1024, 64, f);
A>Остается как-то выделить 64Кб памяти...

Скажите, а вот эти две строки не одинаково ли будут работать?

fread(buf, 1024, 64, f);
fread(buf, 1024*64, 1, f);
Re[4]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 03.03.05 00:31
Оценка:
Ну вообщем наваял что-то на уровне интуиции.
Вроде бы работает, хотя есть вопросы.
Например, при выделении памяти под буфер

buf = new(char[sbuf])

Почему он не пустой. В нем сразу есть какой-то мусор.
И еще. Если сделать вот так,

sbuf = (atoi(_argv[2]))*1024;

то переменная равна нулю. Приходится делать вот так

sbuf = (atoi(_argv[2]));
sbuf *= 1024;

А вот и сам текст.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <dos.h>

int main(int argc, char ** argv){

/* Переменные для работы с файлом */
    FILE *stream;
    char *buf;
    long sbuf;
    long rd;

    /* Переменные для подсчета времени */
    time_t tm1, tm2;

    clrscr(); // очистка экрана

/* Открываем файл на чтение.
    Если ошибка - выведи сообщение и прекрати работу. */
 if ((stream = fopen(_argv[1],"r")) == NULL)
     {
      fprintf(stderr, "Cannot open output file.\n");
      return 1;
     }

     /* размер буфера */
     sbuf = (atoi(_argv[2]));
     sbuf*=1024;

     /* Выделяем память для буфера.
         Если ошибка - выведи сообщение и прекрати работу. */
     if((buf = new(char[sbuf]))==NULL)
        {
         printf("Not enough memory to allocate buffer\n");
         return -1;
        };

     /* засекаем время старта */
     tm1 = time(NULL);

     /* читаем и выводим на экран пока не будет конец файла,
         т.е. пока возвращаемый функцией результат будет положительным */
     do{
      rd = (unsigned int) fread(buf, sbuf, 1, stream);
      printf(buf);
     } while(rd>0);

     /* засекаем время конца считывания */
     tm2 = time(NULL);

     /* закрываем файл */
     fclose(stream);

     /* освобождаем память, выделенную под буфер */
     delete(buf);

     /* выводим на экран результаты работы программы */
     printf("\n\n==============================================");
     printf("\nРазмер буфера: %ld kb",sbuf/1024);
     printf("\nВремя обработки: %ld сек.",tm2-tm1);

 return 0;
}
Re[5]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 03.03.05 05:34
Оценка: 10 (1)
Здравствуйте, Egor, Вы писали:

E>Ну вообщем наваял что-то на уровне интуиции.

E>Вроде бы работает, хотя есть вопросы.
E>Например, при выделении памяти под буфер

E>
E>buf = new(char[sbuf])
E>

E>Почему он не пустой. В нем сразу есть какой-то мусор.
Оператор new всего-лишь выделяет свободный (т.е. не занятый другими программами) участок памяти под твою программу и возвращает его адрес в памяти. Он не заполняет его нулями. То, что ты называешь мусором на самом деле есть отрывок неких данных, которые уже никому не нужны (возможно, другая программа завершилась и этот участок памяти стал свободным). Если тебе надо заполнить этот участок нулями, используй функцию memset(buff, 0, num_bytes). Или выделяй память функцией calloc — она заполняет нулями сразу.

E>
E>sbuf = (atoi(_argv[2]))*1024;
E>

E>то переменная равна нулю. Приходится делать вот так
E>
E>sbuf = (atoi(_argv[2]));
E>sbuf *= 1024;
E>

На самом деле так и должно быть. Попробую объяснить: переменная sbuf имеет тип long (4 байта), а функция atoi возвращает тип int (2 байта). Происходит следующее: компилятор видит, что перемножаются 2 числа типа int, и, соответственно, перемножает их как int'ы и результат тоже будет int. Перемножив 64*1024 получим число 65536, которое в двоичной записи имеет вид:
00000000 00000001 00000000 00000000  разряды
   4        3        2        1      байты

В промежуточный результат будет записан 0 (первые два байта — размер int). И только потом произойдет приведение типов, и эти два байта станут четырьмя. Типы приводятся так: если от знакового к знаковому, то недостающие два байта заполняются последним (знаковым) битом. В остальных же случаях, недостающие байты заполняются нулями. При приведении от большего по диапазону к меньшему лишние старшие байты просто тупо обрезаются.
char => int
11111110 bin = -2 dec   =>  11111111 11111110 bin = -2 dec   знаковый бит = 1
01111111 bin = 127 dec  =>  00000000 01111111 bin = 127 dec  знаковый бит = 0

char => unsigned int
11111110 bin = -2 dec   =>  00000000 11111110 bin = 254 dec  заполняем нулями
01111111 bin = 127 dec  =>  00000000 01111111 bin = 127 dec  заполняем нулями

int => char
00000001 00000000 bin = 128 dec   =>  00000000 bin = 0 dec
11111111 00000001 bin = -255 dec  =>  00000001 bin = 1 dec
11111111 10000001 bin = -127 dec  =>  10000001 bin = -127 dec

long => unsigned int
00000000 00000001 00000000 00000000 bin = 65536(64Kb) dec   =>  00000000 00000000 bin = 0 dec

Значит, чтобы правильно перемножить два числа, надо сделать приведение типов до того как произойдет перемножение:
sbuf = (long)atoi(_argv[2])*1024;
// Заметь, что приведение типа имеет больший приоритет, чем умножение. Т.е. это эквивалентно следующему:
sbuf = ( (long)atoi(_argv[2]) )*1024;

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

E>Скажите, а вот эти две строки не одинаково ли будут работать?

E>fread(buf, 1024, 64, f);
E>fread(buf, 1024*64, 1, f);
Они будут одинаково работать только в случае, если 1024*64 не вылезает за пределы диапазона unsigned int, а он вылеает (смотри пример выше). Поэтому 1024*64 на самом деле будет равно нулю... Значит надо использовать fread(buf, 1024, 64, f); но тут надо учесть, что читать он будет блоками по 1 килобайту и, если в конце файла будет, скажем 1023 байта, то он их не считает. Необходимо будет в самом конце после цикла сделать вызов fread(buf, 1, 1023, f); и обработать эти байты отдельно.
Эта же проблема стоит и при выделении памяти: ты фактически выделяешь 0 байт и твоя программа однажды может громко вывалиться с эксепшеном. Странно, что он вообще выделяет блок памяти размером 0 байтов... Таким способом ты можешь выделить максимум 65535 байт, что на один байт меньше нужных тебе 64Кб. Еще можно попробовать функцию calloc(64, 1024). Если не поможет, то тогда уже farmalloc — эта точно сработает, но с такой памятью необходимо "особенное" обращение
Re[6]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 03.03.05 07:17
Оценка:
Здравствуйте, ansi, Вы писали:

A>Они будут одинаково работать только в случае, если 1024*64 не вылезает за пределы диапазона unsigned int, а он вылеает (смотри пример выше). Поэтому 1024*64 на самом деле будет равно нулю... Значит надо использовать fread(buf, 1024, 64, f); но тут надо учесть, что читать он будет блоками по 1 килобайту и, если в конце файла будет, скажем 1023 байта, то он их не считает. Необходимо будет в самом конце после цикла сделать вызов fread(buf, 1, 1023, f); и обработать эти байты отдельно.

A>Эта же проблема стоит и при выделении памяти: ты фактически выделяешь 0 байт и твоя программа однажды может громко вывалиться с эксепшеном. Странно, что он вообще выделяет блок памяти размером 0 байтов... Таким способом ты можешь выделить максимум 65535 байт, что на один байт меньше нужных тебе 64Кб. Еще можно попробовать функцию calloc(64, 1024). Если не поможет, то тогда уже farmalloc — эта точно сработает, но с такой памятью необходимо "особенное" обращение

Суть программы в следующем — прочитать один большой файл разными размерами буфера (от 1Кб до 64Кб), вывести на экран символы и посчитать затраченное на все это время. Затем построить график зависимости времени от размера буфера.
Так вот если размер буфера увеличиваем — время уменьшается. Доходим до 64Кб — хлоп , а прочитать то нельзя.
Если последовать вышеуказонному совету fread(buf, 1024, 64, f), то получися, что чтение будет проводится по 1024 байт 64 раза (я прав?), и смысл такого чтения для моего случая пропадает.
Попробовал все функции, которые мне советовали. От calloc, farcalloc, malloc, farmalloc — ничего не получается.

if((buf = (char *) farmalloc(sbuf))==NULL)

buf всегда = NULL;

Уф-ф-ф... запутался я совсем.
Спасибо за помощь.
Re[7]: Не могу понять этот Borland C++ 3.1
От: Privalov  
Дата: 03.03.05 14:27
Оценка:
Здравствуйте, Egor, Вы писали:

E>Попробовал все функции, которые мне советовали. От calloc, farcalloc, malloc, farmalloc — ничего не получается.


E>
E>if((buf = (char *) farmalloc(sbuf))==NULL)
E>

E>buf всегда = NULL;

E>Уф-ф-ф... запутался я совсем.

E>Спасибо за помощь.

Объяви sbuf как huge и попробуй еще раз farmalloc или farcalloc.

>

char huge *cbuf;
...
if((buf = (huge char *) farmalloc(sbuf))==NULL)
Re[7]: Не могу понять этот Borland C++ 3.1
От: ansi  
Дата: 04.03.05 00:21
Оценка:
E>Если последовать вышеуказонному совету fread(buf, 1024, 64, f), то получися, что чтение будет проводится по 1024 байт 64 раза (я прав?), и смысл такого чтения для моего случая пропадает.
Я не знаю, может там такая оптимизация есть. На самом деле на всех уровнях уже все давно буферизовано (и сам винт буферизует, и ОС, и не исключено, что эти функции тоже...). С другой стороны, странно было бы, если бы во время вызова fread(buf, 1, 30000, f) он читал 30000 раз...

E>Попробовал все функции, которые мне советовали. От calloc, farcalloc, malloc, farmalloc — ничего не получается.

E>
E>if((buf = (char *) farmalloc(sbuf))==NULL)
E>

E>buf всегда = NULL;
Да, силенок у него почему-то не хватает. И тебе правильно советовали использовать char far *, но это тоже не поможет — память все равно не выделяет(???) да и fread принимает обычный указатель (2 байта), а far-указатель занимает 4 байта... И модель на это дело не влияет. Короче, дрянь дело. Если не стоит острой необходимости писать все это на BC++ 3.1, то воспользуйся 32-разрядным компилятором (например тот же Visual C++) — там с этим проблем точно не будет (конечно, если ты не собираешься читать в 4Гб буфер ). У паскаля, кстати, была бы абсолютно та же проблема, во всяком случае у борландовского. Если брать Free Pascal Compiler, то он уже 32-разрядный, насколько я помню.

E>Уф-ф-ф... запутался я совсем.

E>Спасибо за помощь.
Да пожалуйста! Заходи, если что
Re[7]: Не могу понять этот Borland C++ 3.1
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.05 05:21
Оценка:
Здравствуйте, Egor, Вы писали:

E>Суть программы в следующем — прочитать один большой файл разными размерами буфера (от 1Кб до 64Кб), вывести на экран символы и посчитать затраченное на все это время. Затем построить график зависимости времени от размера буфера.

E>Так вот если размер буфера увеличиваем — время уменьшается. Доходим до 64Кб — хлоп , а прочитать то нельзя.

Вот блин, никогда не думал, что придется вспоминать программирование под MS-DOS.
Давно это было, надеюсь, что меня поправят, если ошибусь.

MS-DOS работает в реальном режиме x86 процессоров. А там память выделяется сегментами, максимальный размер которых не может превышать 64K (т.к. смещение внутри сегмента определяется 16-битными значениями). Но! Ты не можешь получить от ОС блок памяти размером 64K, т.к. в каждом выделеном блоке ОС хранит еще, если не ошибаюсь, 16-байтовый блок MCB (Memory Control Block). Т.е., теоритический максимум в реальном режиме -- (64K — 16). Даже, если run-time Borland-а организует свое управление хипом, без управляющих блоков в каждом выделенном через malloc фрагменте, все равно память он получает от ОС и, поэтому, не может выделить тебе непрерывный блок объемом 64K.

Можно поменять модель памяти на huge для всего приложения. Тогда farmalloc сможет выделить тебе блок 64K. Но, по-моему, это будет не непрерывный блок. А блок из двух сегментов, вначале каждого из которых будет MS-DOS-ный MCB. И "плавный" переход через их границу обеспечивается просто хитрой реализацией работы с huge-указателями в компиляторе. Хотя на уровне (*p++) или memcpy/memmove в программе на это можно не заморачиваться.

Разницы между fread(buf,1024,64,f) и fread(buf,1024*64,1,f) нет, т.к. она все равно обращается к системной функции через прерывание int 21, в которую передается общее количество байт для чтения в виде 16-ти битового числа. А т.к. 1024*64 в 16-ти битах дает 0, то это эквивалентно fread(buf,0,0,f).
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 04.03.05 06:19
Оценка:
Здравствуйте, eao197, Вы писали:


E>MS-DOS работает в реальном режиме x86 процессоров. А там память выделяется сегментами, максимальный размер которых не может превышать 64K (т.к. смещение внутри сегмента определяется 16-битными значениями). Но! Ты не можешь получить от ОС блок памяти размером 64K, т.к. в каждом выделеном блоке ОС хранит еще, если не ошибаюсь, 16-байтовый блок MCB (Memory Control Block). Т.е., теоритический максимум в реальном режиме -- (64K — 16)


64-16=48Кб
у меня выделяет 59Кб, а вот 60 уже нет.

E>Разницы между fread(buf,1024,64,f) и fread(buf,1024*64,1,f) нет, т.к. она все равно обращается к системной функции через прерывание int 21, в которую передается общее количество байт для чтения в виде 16-ти битового числа.


Согласен. Практика показала одинаковые результаты.
Спасибо всем кто ответил. Может еще когда спрошу.
Re[9]: Не могу понять этот Borland C++ 3.1
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.05 07:58
Оценка:
Здравствуйте, Egor, Вы писали:

E>Здравствуйте, eao197, Вы писали:



E>>MS-DOS работает в реальном режиме x86 процессоров. А там память выделяется сегментами, максимальный размер которых не может превышать 64K (т.к. смещение внутри сегмента определяется 16-битными значениями). Но! Ты не можешь получить от ОС блок памяти размером 64K, т.к. в каждом выделеном блоке ОС хранит еще, если не ошибаюсь, 16-байтовый блок MCB (Memory Control Block). Т.е., теоритический максимум в реальном режиме -- (64K — 16)


E>64-16=48Кб

E>у меня выделяет 59Кб, а вот 60 уже нет.

Я же написал (64K — 16), а не (64K — 16K)
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Не могу понять этот Borland C++ 3.1
От: Egor  
Дата: 04.03.05 08:04
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я же написал (64K — 16), а не (64K — 16K)


А, ну да. Извиняюсь.
Мартышка к старости слаба глазами стала
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.