C++ vector (Форк на C)

Модератор: Модераторы разделов

BratSinot
Сообщения: 812
ОС: Slackware64

C++ vector

Сообщение BratSinot »

Доброго времени суток!

Когда-то требовалось переписать некоторые C++ операции с vector, на C. Тофарищ NickLion переписал это:

Код: Выделить всё

buffer.insert(buffer.end(), array, array + bytes);

На это:

Код: Выделить всё

*buffer = (char*)realloc(*buffer, (*bufsize+bytes)*sizeof(char));
memcpy( *buffer + *bufsize, array, bytes * sizeof( char ) );
*bufsize += bytes;

Так вот, этот код работает, но нормально он работает у меня только на GNU/Linux amd64. На Windows собирал через MInGW и Visual C++ 2008 и получал, что маленькие файлы он загрузит, а большие ОЧЕНЬ-ОЧЕНЬ-ОЧЕНЬ долго грузит.
Можно ли это как-нибудь облагородить?
Спасибо сказали:
Аватара пользователя
agentprog
Сообщения: 362
Статус: Ad Astra per aspera
ОС: openSUSE 11.4, Arch

Re: C++ vector

Сообщение agentprog »

если это делается в цикле, то это может быть очень долгим, потому что периодически realloc() нужно перемещать кусок памяти в другое место. если нужно что-то часто добавлять в массив, я заранее резервирую место элементов на 10-15 и "реаалочу" только в случае, когда выделенное место закончилось и надо выделить еще.
No problems - just solutions!
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++ vector

Сообщение NickLion »

Да, если такая операция выполняется часто. то лучше резервировать мето заранее. Правильнее даже будет резервировать не на 10-15 элементов, а, к примеру в 2 раза. Если жалко - в 1.5 возьмите :) Ну, в таком духе: зарезервировали сразу 16 байт. Если кончилось - добавили ещё 16 (в сумме 32). Закончились - ещё 32 выделили, затем 64 и т.д.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++ vector

Сообщение drBatty »

Если читается именно файл (НЕ поток!), то можно сначала узнать его размер (например ftell+fgetpos), а потом выделить нужное количество памяти. Можно и с потоком такое проделать конечно, только надо проверять ошибки - например у /dev/zero нет конца, в этом случае можно выделять память начиная с малого числа (например 100), а потом удваивать размер при необходимости, как писал NickLion
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: C++ vector

Сообщение BratSinot »

Так теперь немного не по теме, но по теме. Я загружаю OGG файл для работы с OpenAL. Под bufferData я стал выделять так:

Код: Выделить всё

bufferData = malloc(ov_pcm_total(&oggFile, -1)*4);

В оперативной памяти вроде занимает столько-же места.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: C++ vector

Сообщение frp »

drBatty писал(а):
26.02.2011 10:37
то можно сначала узнать его размер (например ftell+fgetpos)

А stat не лучше подойдет для узнавания размера?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++ vector

Сообщение drBatty »

frp писал(а):
26.02.2011 19:08
А stat не лучше подойдет для узнавания размера?

если у вас имя файла - да. а если УЖЕ открытый поток - не думаю. по обстоятельствам.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: