Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> STL list или vector 
:(
    Опции темы
lamber
Дата 7.1.2011, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



Столкнулся с мало знакомым мне явлением, записываю 40мб файл в list и получаю размер программы в памяти порядка 200мб. Но это пол беды как только начинаю орабатывать получившийся массив выкидывает с оибкой меня bad_alloc, не может выделить память, хотя дело в том что я и не выделяю память в своей функции. Прохожусь по данном list' итератором. Вот думаю может использовать вместо list vector. Правда в vector файл загружается достаточно долго (навернное ввиду того что огромное количество new delete), но хотябы не вылеает ошибка памяти. Плотно с STL я не знаком подскажите кто компитентен
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



lamber

По умолчанию используй вектор, если задача не требует иного.

Цитата(lamber @  7.1.2011,  16:44 Найти цитируемый пост)
Правда в vector файл загружается достаточно долго (навернное ввиду того что огромное количество new delete)

можно примерно подсчитать количество загружаемых данных и предварительно попросить вектор выделить нужное количество памяти.
Код

std::vector<int> x(10000);


вообще у list-а есть overhead в плане расхода памяти, кроме данных он хранит + 2 указателя (на большинстве платформ 8 байтов) для каждого элемента. Возможно в этом причина нехватки памяти.
40Mb - 41943040 байт, в виде int - это 10485760 элемента, для каждого элемента храниться 12 байт - 10485760 * 12 = 120Mb.
PM   Вверх
lamber
Дата 7.1.2011, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



у меня list<string>
а вот сколько элементов там будет по разному может быть очень много а может и не очень )))
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(lamber @  7.1.2011,  19:01 Найти цитируемый пост)
у меня list<string>

все равно, оверхэда это не отменяет. Прежде чем использовать любой из контейнеров STL следует понимать как он работает и как хранит данные в памяти.
PM   Вверх
lamber
Дата 7.1.2011, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



опять танцы с бубнами, не могу задача все таже 
есть два файла зашружаем их
первый в vector<string>
второй в map<char<vector<string>>

формат перового файла
somedata key somedata \n
key somedata key somedata \n

второго файла
key=>value
key=>value

код загрузки файлов
загрузка первого файла

Код

    string line;
    ifstream infile(filename,ios_base::in);
    while (getline(infile, line, '\n'))
  {
      line.erase(remove(line.begin(),line.end(),' '),line.end());
      if(line!="")
        data.push_back(line);
  }


загрузка второго файла
Код

    string line;
    key_value temp;
    ifstream infile(filename,ios_base::in);
    while (getline(infile, line, '\n'))
  {
      line.erase(remove(line.begin(),line.end(),' '),line.end());
      if(line!="")
    if(explode(line,temp))
        data[line[0]].push_back(temp);
  }
 

 
 key_value это структура 
Код

 struct key_value{
 string key;
 string value; 
 };


вот основная ф-ция где происходит обработка
Код

    int nflush=0;
    int counter=0;
    string str_buffer;    
    for(size_t start=0;start<fIn.size();start++)
    {
        temp=fIn[start];
        for(size_t iter=0;iter<data[temp[0]].size();iter++)
        {
            if(compare(temp,data[temp[0]][iter])){
                nflush++;
                counter++;
                temp=replaceAll(temp,data[temp[0]][iter].value);
                str_buffer.append(temp+"\r\n");
                if(nflush>=500)
                {
                    data.SaveToFile("outputs.txt",str_buffer);
                    wsprintfA(buffer,"Progress: %d",counter);
                    SetWindowTextA(GetDlgItem(thwnd,IDTEXT),buffer);
                    nflush=0;
                    str_buffer.clear();
                }
            }


        }



    }

    MessageBoxA(NULL,"Замена завершенна","MSG",MB_OK);
    _endthreadex(0);
    return 0;
}


Не знаю почему, но программа вылетает выдавай сообщение _Roff off end (после того как выдало ошибку выбрасывает на этот участок кода в stl при использовании контейнера list вылетает из bad_alloc'а) . Вообщем-то в большей степени это продолжения моего топика про обработку больших файлов. Надеюсь на помощь azesmcar'а )))
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



lamber

Не совсем понял, откуда list, у тебя ведь vector?
Цитата(lamber @  7.1.2011,  20:27 Найти цитируемый пост)
выбрасывает на этот участок кода в stl при использовании контейнера list


хотя в общем итоге у тебя просто памяти не хватает, видимо файлы слишком большие, чтобы их загружать в оперативную память. Хотелось бы побольше разузнать про задачу и алгоритм ее решения, что за файлы (как я понял их два), какого размера и что в итоге нужно получить?
PM   Вверх
lamber
Дата 7.1.2011, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



В этом топике все изложил http://forum.vingrad.ru/forum/topic-319530...1%8B%D1%85.html


PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



lamber

размер второго файла тоже большой?

Добавлено @ 20:47
Цитата(lamber @  6.1.2011,  18:34 Найти цитируемый пост)
достаточно большие от 30-100мб (как первый так и второй) 

ок. вижу, что во втором файле занимает место, ключ или значение?

Это сообщение отредактировал(а) azesmcar - 7.1.2011, 20:47
PM   Вверх
lamber
Дата 7.1.2011, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



Отсортировать а потом загружать частями :? Как это лучше использовать и алгоритм какой использовать. Лучше загрузить сначала в контейнер потом отсортировать сохранить в файл обратно а потом загружать :? В первом файле который и является самым большим, key не всегда в одном и том же месте, как мне его сортировать :?
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



lamber

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

Это сообщение отредактировал(а) azesmcar - 7.1.2011, 20:52
PM   Вверх
lamber
Дата 7.1.2011, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



во втором файле большее место занимает ключ как правило.
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(lamber @  7.1.2011,  20:49 Найти цитируемый пост)
во втором файле большее место занимает ключ как правило. 

ну, в крайнем случае можно загрузить не сам файл, а создать какие-то индексы. 
  • отсортировать второй файл
  • загрузить в map индексы
  • искать по индексу ключа в файле
Например 

файл
Цитата

key1=1
key2=2
key3=3
key4=4

создается индекс
Цитата

key1 .. key2 -> 0 .. 13
key3 .. key4 -> 14 .. 27

т.е. указываются позиции, с которых надо искать в файле некий range
чем больше range - тем больше время поиска, но меньше расход памяти.

прочитали из второго файла ключ, например key3
ищем в map-е индексов его положение в файле, он располагается между позициями 14 и 27, переходим на эту позицию и ищем оттуда перебором.

но если второй файл можно загрузить в память - то лучше конечно загружать.

и еще...если ключи слишком длинные их можно хэшировать и хранить не сам ключ а его хэш.

надеюсь понятно описал?

Это сообщение отредактировал(а) azesmcar - 7.1.2011, 21:02
PM   Вверх
lamber
Дата 7.1.2011, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



Не совсем понятно как по индексу искать в файле, т.е. как можно свободно путшествовать по файлу :?

я так поняимаю вид должен быть примерно следующий.
map<char<vector<int>> 
где char у нас будет первый символ ключа а vector<int> это номер строк где он содержится. 

Но вод беда в том что первый файл может и не иметь четкой структуры я имеюю ввидуто что во втором файле все организованно все имеет вид
key=>value

то первй фал это некоторые предложения где key может идти в организованной форме так и без нее.
PM MAIL   Вверх
azesmcar
Дата 7.1.2011, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(lamber @  7.1.2011,  21:11 Найти цитируемый пост)
Не совсем понятно как по индексу искать в файле, т.е. как можно свободно путшествовать по файлу :?

средствами стандартной библиотеки. Функцией seek если быть точным.


Цитата(lamber @  7.1.2011,  21:11 Найти цитируемый пост)
я так поняимаю вид должен быть примерно следующий.
map<char<vector<int>> 
где char у нас будет первый символ ключа а vector<int> это номер строк где он содержится. 

нет
Код

map<string_range, int_range> index;

что-то вроде этого, где
string_range - структура, хранящая key_from и key_to (это отрезок ключей) и соответствующий этому отрезку offset в файле.

Цитата(lamber @  7.1.2011,  21:11 Найти цитируемый пост)
Но вод беда в том что первый файл может и не иметь четкой структуры я имеюю ввидуто что во втором файле все организованно все имеет вид
key=>value

да, но это и не нужно.

алгоритм примерно следующий
Код

while (something_to_read)
{
    data d = file1.read_next();
    data replacement = data_from_file2.find(d);
    if (replacement )
        file3.write(replacement);
    else
        file3.write(d);
}

ну и если не удастся загрузить второй файл в память, то придется еще и искать его ключ по файлу, в этом случае файл придется сортировать, так-как искать что-то в чем-то НЕ отсортированном не самая удачная из идей smile

Желательно конечно загрузить второй файл в память. Попробуй сперва это, если ключи очень длинные - храни хэш.

Это сообщение отредактировал(а) azesmcar - 7.1.2011, 21:23
PM   Вверх
lamber
Дата 7.1.2011, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 20.12.2008

Репутация: нет
Всего: нет



### я думал это казуальная задача а выходит на деле далеко не так. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1253 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.