выделить в кучу - PullRequest
       4

выделить в кучу

0 голосов
/ 23 февраля 2012

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

#include <iostream> 
#include <string>   
#include <fstream>  

using namespace std ;

int main() {

    char *file_name = "doc.txt" ; 

    ifstream fin ;
    fin.open( file_name ) ;

    if( ! fin ) {
         cout << "Problems opening " << file_name << endl ;
         return -1 ;
    }

    const unsigned MAX = 100 ; 
    string doc[MAX] ;

    unsigned word_count = 0 ;
    //while( fin >> doc[ word_count++ ] ) ;

    while( fin >> doc[ word_count ] ) {
         cout << doc[ word_count ] << endl ;
         word_count ++ ;
    }
    fin.close() ;

    return 0 ;
}   

Ответы [ 4 ]

2 голосов
/ 23 февраля 2012

Хорошо, если я понимаю, что вы здесь делаете, вы читаете в массив с именем doc.Однако, поскольку массивы должны размещаться статически, вы не достигаете своей цели, чтобы это было более динамичным.Есть способы сделать это, например, использовать vector, например,

vector<string> doc;
string newestInput;
while( fin >> newestInput ) {
     cout << newestInput << endl ;
     doc.push_back(newestInput);
}
1 голос
/ 23 февраля 2012

Не выделять все пространство заранее имеет смысл, только если вы не собираетесь читать весь файл. Если это действительно так, у вас есть несколько вариантов:

  • Считайте файл кусками (либо заранее определенной длины, либо в строках) и сохраните их в std::list<std::string>. Вы также можете использовать std::vector<std::string>, но это перераспределяет память по мере ее роста, что может привести к нехватке памяти раньше, чем это строго необходимо (из-за фрагментации и необходимости поддерживать как старый, так и новый блок памяти «живым» в одновременно с копированием элементов).
  • В Windows используйте VirtualAlloc до резерв объем памяти, равный размеру файла, а затем коммит постранично, когда вы читаете файл. Таким образом, вы никогда не будете совершать больше, чем вам действительно нужно.
  • В Windows используйте отображенный в памяти файл.

Кстати, вы можете получить размер файла (главным образом) переносимым способом, используя функцию _stat (читайте поле st_size).

0 голосов
/ 23 февраля 2012

Вы можете использовать std::vector и хранить там слова / строки, чтобы у вас не было значения , чтобы узнать размер.

В файле есть хорошая справочная статьяI / O здесь .При чтении текстового файла они читают построчно в цикле while( myFile.good() ) и получают текущую строку, используя getline(myFile, line), где myFile - ваш объект ifstream, а line - строка, в которой вы хотите сохранить текущую строку.

В примере они просто выводят текущую строку, но вы также можете добавить ее к вектору, если хотите.

И, просто из любопытства, для чего вы используете оператор >>?Не может ли быть достигнуто то же самое с getline()?

0 голосов
/ 23 февраля 2012

Лучше всего использовать контейнер STL, например vector.Это позволяет вам динамически распределять память по мере необходимости.

vector<string> doc;
string word;

while ( !fin.eof() )
{
   fin >> word;
   doc.push_back(word);
   cout << word << end;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...